[Java] Regex multiple line

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Maxxi
  • Registratie: Mei 2004
  • Laatst online: 19-04 19:18
Situatie:
Java programma leest doormiddel van een regex een tekstfile in. Deze tekstfile bevat schaakzetten, dit gebeurd vaak in een vaste notatie namelijk PGN.

Een PGN file ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. e4 e6 2. d4 d5 3. Nd2 Be7 4. Ngf3 Nf6 5. Bd3 c5 6. e5 Nfd7 7. c3 Nc6 8. O-O
a5 9. Re1 cxd4 10. cxd4 Qb6 11. Nb1 Nxd4 12. Nxd4 Qxd4 13. Nc3 Bc5 14. Nb5
Qxf2+ 15. Kh1 O-O 16. Bg5 Bb6 17. Qh5 g6 18. Qh6 Bd8 19. Bxd8 { [%clk 0:19.44]
} Rxd8 20. Rf1 { [%clk 0:14.17] } Qxb2 21. Rae1 { [%clk 0:12.38] } Rf8 22. Nc7
{ [%clk 0:09.58] } Nxe5 { [%clk 0:19.59] } 23. Bb1 { [%clk 0:06.41] } Rb8 {
[%clk 0:18.18] } 24. Qf4 { [%clk 0:04.47] } Nc6 { [%clk 0:17.36] } 25. Ne8 {
[%clk 0:04.20] } f5 { [%clk 0:16.13] } 26. Nc7 { [%clk 0:02.37] } Qf6 { [%clk
0:14.50] } 27. Qd6 { [%clk 0:02.00] } Rd8 { [%clk 0:09.37] } 28. Qc5 { [%clk
0:01.51] } Kf7 { [%clk 0:07.26] } 29. Bc2 { [%clk 0:01.16] } Qe7 { [%clk
0:07.06] } 30. Qe3 { [%clk 0:00.20] } Qxc7 { [%clk 0:06.42] } 31. g4 { [%clk
0:00.19] } Kg8 { [%clk 0:06.02] } 32. gxf5 { [%clk 0:00.16] } exf5 { [%clk
0:05.52] } 33. Qg5 { [%clk 0:00.11] } Qf7 { [%clk 0:05.20] } 34. h4 { [%clk
0:00.07] } Be6 { [%clk 0:04.40] } 35. h5 { [%clk 0:00.06] } Rf8 { [%clk
0:04.15] } 36. hxg6 { [%clk 0:00.05] } hxg6 { [%clk 0:04.03] } 37. Rg1 { [%clk
0:00.04] } Kg7 0-1
6. e5 Nfd7


Zoals je misschien meteen zag begint elke zet op het bord met het zetnummer (1. , 2. etc). Vervolgens komt de letter die het stuk vertegenwoordig (behalve bij pionnen daar is geen letter voor). Gevolgd door het "beginvlak" en het "eindvlak" op het bord.

Nu heb een redelijk stuk al voor elkaar, de enige situatie waarbij het fout gaat is wanneer een zet verspreid is over twee regels. Zoals bij zet 8 en 14. Ik zag dat er parameters waren voor multiline, maar dat is niet helemaal wat zoek.

Hoe kan ik dit nu het beste oplossen? Mijn code tot nu toe:
code:
1
2
3
4
5
6
String startNumber = "[1-9]{1,3}[.] "; 
String rokeren = "[O][-][O]";
String move = "[a-zA-Z]{1,3}[1-9] ";
String or = "|";

Pattern.compile(startNumber +move+move + or+ startNumber + "(" +rokeren+")");


Output:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. e4 e6 
2. d4 d5 
3. Nd2 Be7 
4. Ngf3 Nf6 
5. Bd3 c5 
6. e5 Nfd7 
7. c3 Nc6 
8. O-O            ---------- hier mist a5
9. Re1 cxd4 
11. Nb1 Nxd4 
12. Nxd4 Qxd4 
13. Nc3 Bc5 
                     --------- hier mist zet 14
16. Bg5 Bb6 
17. Qh5 g6 
18. Qh6 Bd8

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Waarom strip je cr\lf's er niet eerst gewoon uit?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Little Penguin
  • Registratie: September 2000
  • Laatst online: 08-06 20:43
Is het niet een idee om de regelovergangen eerst te vervangen door een whitespace (spatie)? Aangezien je de zetten kunt splitsen op hun nummertje...

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:27

Creepy

Tactical Espionage Splatterer

Je zult i.p.v. de spatie waarschijjlijk moeten matchen op een whitespace charachter, dat is \s in je regexp. Dat matched o.a. spatie, tab en een newline
\s: A whitespace character: [ \t\n\x0B\f\r]

[ Voor 3% gewijzigd door Creepy op 10-04-2009 10:57 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Maxxi
  • Registratie: Mei 2004
  • Laatst online: 19-04 19:18
RobIII schreef op vrijdag 10 april 2009 @ 10:55:
Waarom strip je cr\lf's er niet eerst gewoon uit?
Bedoel je dat je eerst de hele reeks met zetten inleest en achter elkaar plakt? Dit zou wel kunnen maar kost wel een hoop performance. En dit uitlezen gebeurd een aantal keren per minute voor meerdere partijen tegelijk.
Little Penguin schreef op vrijdag 10 april 2009 @ 10:56:
Is het niet een idee om de regelovergangen eerst te vervangen door een whitespace (spatie)? Aangezien je de zetten kunt splitsen op hun nummertje...
Ook dit kan, maar een regelovergang kan ook bv. midden in een zetnummer zitten. Dus 8 \n .

De laaste opmerking van Creepy begrijp ik niet goed?

Zelf dacht ik aan nog een andere oplossing:
Vindt het einde van de regel, en zoek de laatse "halve" zet, knip deze en plak hem er voor bij de volgende regel. Maar dat is ook nog niet zo makkelijk.
code:
1
Pattern.compile("^[1-9]{1,3}[.] *.* [.]{1,11}&");

[ Voor 19% gewijzigd door Maxxi op 10-04-2009 11:22 ]


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 17-09 18:39

Matis

Rubber Rocket

Maxxi schreef op vrijdag 10 april 2009 @ 11:20:
Ook dit kan, maar een regelovergang kan ook bv. midden in een zetnummer zitten. Dus 8 \n .

De laaste opmerking van Creepy begrijp ik niet goed?
Je geeft in de regel erboven het antwoord op je vraag.

Wat Creepy zegt is dat dat je moet checken of je newline omsloten wordt door whitespaces e.d.

Daarnaast vind ik het vreemd dat wanneer je de linefeed replaced door niets je performance afneemt :o

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • Little Penguin
  • Registratie: September 2000
  • Laatst online: 08-06 20:43
Maxxi schreef op vrijdag 10 april 2009 @ 11:20:
[...]
Ook dit kan, maar een regelovergang kan ook bv. midden in een zetnummer zitten. Dus 8 \n .
Maar zit deze "onverwachte regelovergang" alleen in het zetnummer? En is het zo dat een punt alleen gebruikt wordt in het zetnummer?

Als aan deze 2 voorwaarde voldaan wordt dan strip je na het vervangen van de regelovergangen gewoon alle spaties voor de punten weg en je bent al klaar...

Is het formaat toch wel geschikt voor het automatisch uitlezen men de computer vraag ik me af??? (Wat ik bedoel is dat er niet tig uitzonderingen kunnen zijn in het geval van een regelovergang - dan wordt je namelijk niet vrolijk als je die allemaal moet gaan opzoeken...)

Acties:
  • 0 Henk 'm!

  • Maxxi
  • Registratie: Mei 2004
  • Laatst online: 19-04 19:18
toaomatis schreef op vrijdag 10 april 2009 @ 11:27:
[...]
Daarnaast vind ik het vreemd dat wanneer je de linefeed replaced door niets je performance afneemt :o
Het replacen niet, maar het achter elkaar plakken van de hele game wel.
Little Penguin schreef op vrijdag 10 april 2009 @ 11:27:
[...]

Maar zit deze "onverwachte regelovergang" alleen in het zetnummer? En is het zo dat een punt alleen gebruikt wordt in het zetnummer?

Als aan deze 2 voorwaarde voldaan wordt dan strip je na het vervangen van de regelovergangen gewoon alle spaties voor de punten weg en je bent al klaar...

Is het formaat toch wel geschikt voor het automatisch uitlezen men de computer vraag ik me af??? (Wat ik bedoel is dat er niet tig uitzonderingen kunnen zijn in het geval van een regelovergang - dan wordt je namelijk niet vrolijk als je die allemaal moet gaan opzoeken...)
Helaas kunnen deze overgangen in theorie overal plaats vinden. De punten worden ook gebruiker in de kloktijden.

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:27

Creepy

Tactical Espionage Splatterer

Maxxi schreef op vrijdag 10 april 2009 @ 11:20:
[...]
De laaste opmerking van Creepy begrijp ik niet goed?
Er zit steeds een spatie in je code
code:
1
String startNumber = "[1-9]{1,3}[.] ";

Note de spatie na [.]. Dat matched altijd en spatie en geen newline ;) Als je de spatie vervangt door een \s matched het zowel een spatie, als een tab, als een newline (en nog wat meer whitespace characters :)

Op http://java.sun.com/j2se/...a/util/regex/Pattern.html kan je terugvinden welke Predefined character classes er zijn voor gebruik in een regexp.

[ Voor 19% gewijzigd door Creepy op 10-04-2009 11:41 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Little Penguin
  • Registratie: September 2000
  • Laatst online: 08-06 20:43
Maxxi schreef op vrijdag 10 april 2009 @ 11:31:
[...]
Helaas kunnen deze overgangen in theorie overal plaats vinden. De punten worden ook gebruiker in de kloktijden.
Is het dan niet een beter idee om de boel op een andere manier dan via reguliere expressies te parsen? Gewoon sequentieel de file doorlopen en bijhouden op welke plaats je je bevindt (en daarop de juiste correctie toepassen als je dan een newline oid tegenkomt...)?

(De kreet waar ik dan aan denk is stack-bases parsen, maar dat kan ook een mismatch in mijn hoofd zijn. :))

Acties:
  • 0 Henk 'm!

  • Maxxi
  • Registratie: Mei 2004
  • Laatst online: 19-04 19:18
Creepy schreef op vrijdag 10 april 2009 @ 11:38:
[...]

Er zit steeds een spatie in je code
code:
1
String startNumber = "[1-9]{1,3}[.] ";

Note de spatie na [.]. Dat matched altijd en spatie en geen newline ;) Als je de spatie vervangt door een \s matched het zowel een spatie, als een tab, als een newline (en nog wat meer whitespace characters :)

Op http://java.sun.com/j2se/...a/util/regex/Pattern.html kan je terugvinden welke Predefined character classes er zijn voor gebruik in een regexp.
Oke das een goede tip! Heb het veranderd. Het probleem blijft alleen dat een newline niet na een "token" komt, maar er ook midden in kan komen.

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:27

Creepy

Tactical Espionage Splatterer

Dan zit er inderdaad niks anders op dan alle newlines eerst eruit te filteren voordat je je regexp los laat.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Maxxi
  • Registratie: Mei 2004
  • Laatst online: 19-04 19:18
Eind van de dag:
Heb inderaad de spaties vervangen door \\s.
En ik lees nu de hele partij uit en plak de regels achter elkaar.

Vervolgens als er een nieuwe partij de de file staat, wordt de vorige verwerkt.

Thanks voor iedereen zn hulp!
Pagina: 1