Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.
Toon posts:

[C#] Regular Expressions

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben hier nu al een hele dag bezig om een deel gegevens uit een tekstbestand te filteren met behulp van regular expressions.

Het desbetreffende type bestand ziet er als volgt uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 gwver=4 cat="ALG" pri=3 port=0 wire="BEL" format=BE slug="Tennis - Davydenko niet langer verdacht van corruptie" code="SPN" size=1097 bdate=091262008163848 sig=i9u)2jp3l6kb4zg88t2pmsfd lang="nl"
                                                                                                                                                                                                                                                                                                                       
Tennis - Davydenko niet langer verdacht van corruptie
    
    PARIJS 12/09 (AFP) = De Rus Nikolay Davydenko (ATP 6) wordt niet
langer verdacht van het vervalsen van tenniswedstrijden. Dat maakte de
vereniging voor tennisprofs ATP vrijdag bekend. Davydenko werd van
corruptie verdacht nadat hij in augustus 2007 in het Poolse Sopot van de
Argentijn Martin Vassallo-Arguello verloren had.
       "De ATP heeft zijn onderzoek beëindigd en heeft geen enkel bewijs
gevonden van een inbreuk op het reglement door de heren Davydenko,
Vassallo-Arguello of wie dan ook die iets met die wedstrijd te maken had",
verklaarde de ATP.
       Een goksite had na de opgave van Davydenko tegen Vassalo-Arguello bij
een 2-6, 6-3 en 2-1 stand in het voordeel van de Argentijn besloten om de
weddenschappen stop te zetten. De site was immers van oordeel dat er
abnormaal hoge sommen waren ingezet op die wedstrijd.
       Davydenko heeft zijn onschuld altijd staande gehouden en is altijd
blijven verklaren dat hij in die bewuste wedstrijd moest opgeven met een
voetblessure.
./.SPJ
    
    09/12/08 16:37
    BELGA/20080912/SPN037/1N


De items die ik er zou moeten uitfilteren zijn:

string gwver = 4
string cat = ALG
string pri = 4
string port = 0
string wire = BEL
string format = BE
string slug = Tennis - Davydenko niet langer verdacht van corruptie
string code = SPN
string size = 1097
string bdate = 091262008163848
string sig = i9u)2jp3l6kb4zg88t2pmsfd
string lang = nl

string title = Tennis - Davydenko niet langer verdacht van corruptie

string text =
PARIJS 12/09 (AFP)
De Rus Nikolay Davydenko (ATP 6) wordt niet
langer verdacht van het vervalsen van tenniswedstrijden. Dat maakte de
vereniging voor tennisprofs ATP vrijdag bekend. Davydenko werd van
corruptie verdacht nadat hij in augustus 2007 in het Poolse Sopot van de
Argentijn Martin Vassallo-Arguello verloren had.
"De ATP heeft zijn onderzoek beëindigd en heeft geen enkel bewijs
gevonden van een inbreuk op het reglement door de heren Davydenko,
Vassallo-Arguello of wie dan ook die iets met die wedstrijd te maken had",
verklaarde de ATP.
Een goksite had na de opgave van Davydenko tegen Vassalo-Arguello bij
een 2-6, 6-3 en 2-1 stand in het voordeel van de Argentijn besloten om de
weddenschappen stop te zetten. De site was immers van oordeel dat er
abnormaal hoge sommen waren ingezet op die wedstrijd.
Davydenko heeft zijn onschuld altijd staande gehouden en is altijd
blijven verklaren dat hij in die bewuste wedstrijd moest opgeven met een
voetblessure.

string end = ./.SPJ

string date = 09/12/08
string time = 16.37
string footer = BELGA/20080912/SPN037/1N

Ik heb met veel moeite en gesukkel reeds de volgende regular expression kunnen opstellen:

code:
1
2
3
4
5
6
gwver=(.*) cat="(.*)" pri=(.*) port=(.*) wire="(.*)" format=(.*) slug="(.*)" code="(.*)" size=(.*) bdate=(.*)

sig=(.*) lang="(.*)"
(.*)
(.*)$(.*)./.(.*)
(.*)\t(.) (.*)(.*)\t(.*)


En in C# doe ik dit als volgt
[code=C#]
string pattern = @"gwver=(.*) cat=""(.*)"" pri=(.*) port=(.*) wire=""(.*)"" format=(.*) slug=""(.*)"" code=""(.*)"" size=(.*) bdate=(.*) sig=(.*) lang=""(.*)"" (.*) (.*)$(.*)./.(.*) (.*)\t(.) (.*)(.*)\t(.*)";
Match matches = Regex.Match(text, pattern, RegexOptions.IgnoreCase);

string test = matches.Groups["gwver"].Value.ToString();
[/code=C#]

Om te testen wil ik enkel de waarde van gwver eens aanroepen, maar dit lukt al niet...

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 01:12
Ik zit aan het eind van m'n werkdag, en heb dus geen zin om reguliere expressies te gaan ontleden, maar dit soort grotere expressies maak ik altijd met Regex Coach. Werkt een stuk eenvoudiger en zie je meteen wat er wel en/of niet gematcht wordt.
Oh ja, nog een tip: begin klein en breidt het steeds verder uit tot je alles hebt wat je nodig hebt.

[ Voor 15% gewijzigd door sig69 op 22-10-2008 17:31 ]

Roomba E5 te koop


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Wat tips:
  • Begin klein, en kijk af en toe of het nog steeds matched. (oeps, bijna een QFT van de post hierboven ;))
  • Gebruik niet (.*) voor een groep, maar geef aan wat je wilt matchen. Dus bijvoorbeeld alles behalve ", dus ([^"]*). Of geen end-of-line-zaken en minimaal een karakter, ([^\r\n]+). Of een datum-achtig-iets ([0-1][0-9]/[0-3][0-9]/[0-9]{2}).
  • Die groepsnamen komen er niet zomaar. Daarvoor moet je zoiets gebruiken
    code:
    1
    
    (?<gwver>[^""]*)
  • text is bijzonder, daar kunnen newlines in voorkomen namelijk. Je kan daarvoor de s gebruiken. Als in
    code:
    1
    
    (?<text>(?s).*?)
    , of met RegexOptions.Singleline als je de . toch nergens anders gebruikt.
  • Stukje met dollarteken snap ik niet.
  • End-of-line-teken matched niet op " ", maar wel op dingen als \s+, [\r\n\]+ of \r?\n (windows heeft wel \r, unix niet)
  • Gebruik \. voor een echte .
  • Let bij IgnoreCase op de juiste Culture.
  • Value is al een string.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Verwijderd

Topicstarter
Ik ben dus eens begonnen met eerst enkel de waarde van gwver uit te lezen op de volgende manier:

C#:
1
2
3
4
5
6
7
8
9
10
                    Regex rx = new Regex(@"gwver=(?<gwver>[^""]*)  ", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                    MatchCollection matches = rx.Matches(text);
                    string gwver = "";
                    foreach (Match match in matches)
                    {
                        GroupCollection groups = match.Groups;
                        gwver = groups["gwver"].Value;
                                     
                    }
                    MessageBox.Show(gwver);


Als ik dit uitvoer dan geeft de messagebox zoals gevraagd de waarde terug van gwver, 4 in dit geval.
Ik moet echter wel zien dat ik een spatie laat tussen het laatste haakje in de regex en de dubbele quote.

Wanneer ik dan ook eens de waarde van cat wil uitlezen dan krijg ik gewoon helemaal geen output meer.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
      Regex rx = new Regex(@"gwver=(?<gwver>[^""]*) cat=(?<cat>[^""]*) ", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                    MatchCollection matches = rx.Matches(text);
                    string gwver = "";
                    string cat = "";
                    foreach (Match match in matches)
                    {
                        GroupCollection groups = match.Groups;
                        gwver = groups["gwver"].Value;
                        cat = groups["cat"].Value;
                                     
                    }
                    MessageBox.Show(gwver + " " + cat);


Tijdens het debuggen merkte ik wel op dat hij hierbij zelfs geen enkele match meer vindt.

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 01:12
Zit je serieus elke keer je project te runnen om te kijken of het werkt? Kijk nog even in mijn vorige reactie aub, scheelt je zo veel tijd, waarschijnlijk had je al klaar geweest.

Roomba E5 te koop


Verwijderd

Topicstarter
Ik ben met die Regex Coach ook al bezig geweest, maar ik zou gaag weten of de manier waarop ik het in C# toepas al klopt?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Waarom gebruik je reguliere expressies? Het formaat lijkt me dermate goed gespecifiseerd dat een simpele parser veel makkelijker toe te passen is.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Ik moet duizenden bestandjes zoals deze inlezen, en ze zijn niet allemaal gelijk aan elkaar. Zo kan er eens een enter te veel staaln, of een stuk regel dat nog aan de voorgaande zin kleeft etc...

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Afgaande op enkel dit berichtje lijkt me het vormaat redelijk simpel:

Een lijstje paramerters in het formaat label=value gescheiden door een spatie (eventueel value binnen quotes wanner er binnen de value spaties zitten

Een lege regel

Een titel

Een lege regel

Een stuk tekst

Een afsluit tekenreeks op een regel "./.SPJ"

nog een paar andere stukjes data.


Het punt is dat de problemen die je schetst hierboven ook je reguliere expressie lastiger maken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • pedorus
  • Registratie: Januari 2008
  • Niet online
sig69 schreef op donderdag 23 oktober 2008 @ 10:18:
Zit je serieus elke keer je project te runnen om te kijken of het werkt? Kijk nog even in mijn vorige reactie aub, scheelt je zo veel tijd, waarschijnlijk had je al klaar geweest.
Je kan tegenwoordig een string in VS.NET gewoon veranderen en even het uitvoerpunt terugzetten, dus opnieuw runnen lijkt me niet nodig. Echt handig is het evengoed niet trouwens.
Verwijderd schreef op donderdag 23 oktober 2008 @ 09:42:
Wanneer ik dan ook eens de waarde van cat wil uitlezen dan krijg ik gewoon helemaal geen output meer.
...
Tijdens het debuggen merkte ik wel op dat hij hierbij zelfs geen enkele match meer vindt.
Het patroon "cat=[^"]* " komt niet voor, want de = wordt gevolgt door een " in de tekst.
gwver is trouwens een nummer en geen tekst zie ik, dus ik zou daar niet een patroon met [^""]*, maar iets als [0-9]+ gebruiken, of iets zonder whitespace... (niet alles klakkeloos overnemen van vage forumgasten natuurlijk ;)).
Denk er ook nog even over na of er altijd een spatie tussen gwver en cat staat, of dat alle whitespace (dus \s+) is toegestaan.
Janoz schreef op donderdag 23 oktober 2008 @ 10:59:
Een afsluit tekenreeks op een regel "./.SPJ"
Deze tekenreeks (iets met "./.") kan misschien in tekst voor komen denk ik. Dan krijgt een normale parser het moeilijk, want die doen gewoonlijk niet aan backtracking. De eerste regel apart parsen is misschien wel een goed idee.

[ Voor 13% gewijzigd door pedorus op 23-10-2008 11:09 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Verwijderd

Topicstarter
Janoz schreef op donderdag 23 oktober 2008 @ 10:59:
Afgaande op enkel dit berichtje lijkt me het vormaat redelijk simpel:

Een lijstje paramerters in het formaat label=value gescheiden door een spatie (eventueel value binnen quotes wanner er binnen de value spaties zitten

Een lege regel

Een titel

Een lege regel

Een stuk tekst

Een afsluit tekenreeks op een regel "./.SPJ"

nog een paar andere stukjes data.


Het punt is dat de problemen die je schetst hierboven ook je reguliere expressie lastiger maken.
Wel dat is het juist niet, die "./.SPJ hangt bij sommige bestandjes achteraan de voorgaande regel geplakt, dus dat maakt het al veel gecompliceerder.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Dan kijk je of een regel eindigd met "./.SPJ" en heb je dat probleem opgelost.


Op dit topic is imho precies van toepassing wat pedorus in een eerder regex topic al aanhaalde:
Some people, when confronted with a problem, think
“I know, I'll use regular expressions.” Now they have two problems.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

pedorus schreef op donderdag 23 oktober 2008 @ 11:01:
Deze tekenreeks (iets met "./.") kan misschien in tekst voor komen denk ik. Dan krijgt een normale parser het moeilijk, want die doen gewoonlijk niet aan backtracking. De eerste regel apart parsen is misschien wel een goed idee.
Eens, maar waarschijnlijk horen de letters en de afsluitende newline er ook bij. Dat maakt de kans kleiner. En vanwege Murphy zal er voor in de tekst vast ook wel een escape sequence beschikbaar zijn (of een restrictie dat dit niet in de body van het item voor mag komen).

Maar ten eerste is dit een universeel probleem dat niet wordt opgelost door reguliere expressies toe te passen, en ten tweede is het vooral een probleem omdat we moeten werken met slechts 1 voorbeeld, terwijl er vast wel ergens een definitie van dit formaat moet zijn.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Zo ziet een ander bestandje er bv uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 gwver=4 cat="UIT" pri=3 port=0 wire="BEL" format=BE slug="Kwalificaties WK voetbal - Zuid-Amerikaanse zone- uitslagen woensdag" code="SPN" size=1421 bdate=091152008110238 sig=ub9d15h58[nujd3()5jf6b1x lang="nl"

Recente scores/          
                                                                                                                                                                                                                                                                                              
Kwalificaties WK voetbal - Zuid-Amerikaanse zone: uitslagen woensdag
    
    BRUSSEL 11/09 (AFP-BELGA) = Uitslagen van de wedstrijden op de achtste
speeldag van de Zuid-Amerikaanse kwalificatiezone voor het WK voetbal van
2010 in Zuid-Afrika:
    
       - Dinsdag

       in Asuncion:
       Paraguay - Venezuela  2-0
       goals
       Paraguay: Cristian Riveros (29), Nelson Haedo (45)

       - Woensdag

       in Montevideo:
       Uruguay - Ecuador    0-0

       in Santiago:
       Chili - Colombia      4-0
       goals
       Chili: Jara (26), Suazo (38), Fuentes (48), Fernandez (71)

       in Rio de Janeiro:
       Brazilië - Bolivia      0-0

       in Lima:
       Peru - Argentinië    1-1
       goals
       Peru: Fano (90 +3)
       Argentinië: Cambiasso (82)
    
       Klassement:   Ptn   W   G   D   V   dv   dt
       1. Paraguay    17   8   5   2   1   16    6
       2. Brazilië    13   8   3   4   1   11    4
       3. Argentinië  13   8   3   4   1   11    5
       4. Chili       13   8   4   1   3   13   12
       5. Uruguay     12   8   3   3   2   16    6
       6. Colombia    10   8   2   4   2    4    7
       7. Ecuador      9   8   2   3   3   10   14
       8. Venezuela    7   8   2   1   5    9   13
       9. Peru         7   8   1   4   3    5   16
            10. Bolivia      5   8   1   2   5    8   20
    
       NVDR: de top 4 mag naar het WK, de vijfde speelt een barrage tegen de
vierde uit de Concacafzone../.CER/TSA
    
    09/11/08 10:28
    BELGA/20080911/SPN014/1N

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Hoewel ik in dit geval het enigsinds met Janoz eens ben is een handige tool om .NET Regexen te maken/testen de tool Expresso. (te vinden via the code project)

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Sorry hoor, maar deze nieuws berichtjes lijken me overduidelijk volgens een bepaald formaat opgemaakt en ik neem aan dat er wel ergens een opmaak definitie te vinden is (eventueel bij het/een persbureau zelf).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op donderdag 23 oktober 2008 @ 11:22:
Zo ziet een ander bestandje er bv uit:
Die is mooi, een titel op meerdere regels :) Hoe zie je nu het verschil tussen titel en tekst?
  • Titel eindigt op slug
  • Tekst begint met STAD, datum, persbureau tussen haakjes
  • Titel begint niet met inspringing
  • Anders (misschien iets met size vanaf de andere kant?)
Heb je nergens een specificatie? (is niet te vinden op internet).

Ik zou, als dit niet eenmalig is, eens gaan praten over de XML feed.

Als dit eenmalig is zou ik het zelf met regexp doen, ivm de backtracking en eenmaligheid, maar ik ben waarschijnlijk iets handiger met regexp. Expresso of Regex tester gebruik ik zelf niet. Dus leer regexp, of maak gewoon een parser (bijvoorbeeld een die van twee kanten werkt, waarbij de tekst of titel overblijft).

Bijpassende quotes :) :
A problem well stated is a problem half solved.
(Charles F. Kettering(?))
A clever person solves a problem. A wise person avoids it.
(Albert Einstein(?))

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Verwijderd

Topicstarter
Ik ben hier ondertussen toch al een eindje verder geraakt, het is mij al gelukt om alle waarden van op de eerste lijn in te lezen met regular expressions:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     Regex rx = new Regex(@"gwver=(.*) cat=""(.*)"" pri=(.*) port=(.*) wire=""(.*)"" format=(.*) slug=""(.*)"" code=""(.*)"" size=(.*) bdate=(.*) sig=(.*) lang=""(.*)""", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                    Match matches = rx.Match(text);

                    belga.gwver = matches.Groups[1].Value;
                    belga.cat = matches.Groups[2].Value;
                    belga.pri = matches.Groups[3].Value;
                    belga.port = matches.Groups[4].Value;
                    belga.wire = matches.Groups[5].Value;
                    belga.format = matches.Groups[6].Value;
                    belga.slug = matches.Groups[7].Value;
                    belga.code = matches.Groups[8].Value;
                    belga.size = matches.Groups[9].Value;
                    belga.bdate = matches.Groups[10].Value;
                    belga.sig = matches.Groups[11].Value;
                    belga.lang = matches.Groups[12].Value;

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
weet je zeker dat ze altijd in dezelfde volgorde staan EN altijd aanwezig zijn?

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


Verwijderd

Topicstarter
Yep dat ben ik zeker.

Maar nu zit ik met het volgende probleem:

code:
1
2
3
4
5
6
7
8
9
^ATennis - ITF Sevilla: Goele Lemmens verliest in eerste ronde
    
    SEVILLA 14/10 (BELGA) = Goele Lemmens (WTA 1026) is uitgeschakeld in
de eerste ronde van het ITF-graveltoernooi in Sevilla (10.000 dollar). Ze
verloor van de Spaanse Rocio De la Torre-Sanchez (WTA 950) in drie sets
met 4-6, 6-0 en 6-0.
    
       Enkel - Eerste ronde:
       Rocio De La Torre-Sanchez (Spa) - Goele Lemmens (BEL) 4-6, 6-0, 6-0


Het zinnetje "^ATennis - ITF Sevilla: Goele Lemmens verliest in eerste ronde" zou ik willen uitlezen met de regex
^A(.*)\n, dit lukt echter maar hij neemt er al de tekst van op de volgende lijnen ook bij, zelfs al zet ik het op singleline.

  • tonyisgaaf
  • Registratie: November 2000
  • Niet online
Verwijderd schreef op donderdag 23 oktober 2008 @ 16:37:
Yep dat ben ik zeker.

Maar nu zit ik met het volgende probleem:

code:
1
2
3
4
5
6
7
8
9
^ATennis - ITF Sevilla: Goele Lemmens verliest in eerste ronde
    
    SEVILLA 14/10 (BELGA) = Goele Lemmens (WTA 1026) is uitgeschakeld in
de eerste ronde van het ITF-graveltoernooi in Sevilla (10.000 dollar). Ze
verloor van de Spaanse Rocio De la Torre-Sanchez (WTA 950) in drie sets
met 4-6, 6-0 en 6-0.
    
       Enkel - Eerste ronde:
       Rocio De La Torre-Sanchez (Spa) - Goele Lemmens (BEL) 4-6, 6-0, 6-0


Het zinnetje "^ATennis - ITF Sevilla: Goele Lemmens verliest in eerste ronde" zou ik willen uitlezen met de regex
^A(.*)\n, dit lukt echter maar hij neemt er al de tekst van op de volgende lijnen ook bij, zelfs al zet ik het op singleline.
Greedy/non-greedy?

NL Weerradar widget Euro Stocks widget Brandstofprijzen widget voor 's Dashboard


Verwijderd

Topicstarter
(.*?) lijkt niets op te lossen

[ Voor 84% gewijzigd door Verwijderd op 24-10-2008 09:56 ]


Verwijderd

Topicstarter
^A(.*?)\n werkt :)

Althans toch in mijn regex editor, want wanneer ik in mijn C# programma de volgende code importeer krijg ik niets terug...

[code=C#]
Regex body = new Regex(@"^A(.*?)\n", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
Match bm = body.Match(text);

belga.title = bm.Groups[1].Value;

[/code=C#]

[ Voor 91% gewijzigd door Verwijderd op 24-10-2008 10:16 ]


  • Daspeed
  • Registratie: Maart 2001
  • Laatst online: 21:43
hint: ^ heeft een speciale betekenis binnen regexen

Verwijderd

Topicstarter
Ik weet het, maar in mijn tekst staat er een rechthoekje maar dat kan ik hier niet afbeelden, gelieve daar niet op te letten.
Pagina: 1