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

[Java]Regular expression

Pagina: 1
Acties:

  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 05-11 10:11
Ik krijg volgende boodschap binnen:
code:
1
2
3
4
[technicalStatus]040[technicalStatus]
[logicalStatus]020[logicalStatus]
[pfysl8_naiy_err]NAS0199 E Geboortedatum 00.00.0000 is foutief.[pfysl8_naiy_err]
[pfysl8_sexe_err]NAS0200 E Geslacht 0 foutief.[pfysl8_sexe_err]


nu zou ik graag dit via een regular expression wat opkuisen om een mooi resultaat te krijgen, helaas kom ik er niet... (let op er is GEEN afsluitende / in de laatste tag [])

onderstaand heb ik wat geprobeerd, maar mijn kennis (en amper gebruik ervan) van regex is heel beperkt :(

Java:
1
2
3
4
5
6
7
8
9
10
11
String input =  "[technicalStatus]020[technicalStatus]"+
                "[logicalStatus]050[logicalStatus]"+
                "[pfysl8_naiy_err]NAS0199 E Geboortedatum 00.00.0000 is foutief.[pfysl8_naiy_err]"+
                "[pfysl8_sexe_err]NAS0200 E Geslacht 0 foutief.[pfysl8_sexe_err]";

 Pattern p = Pattern.compile("\\[(\\w\\p{Punct})*[^\\]]*\\].*?\\[(\\1)\\]");
 String[] result = p.split(input);

 for ( int i = 0; i < result.length; i++) {
    System.err.println(i + " " + result[i] );
}


wat is mijn rederning ?

Eerst zoeken naar een [ met daarin alles wat een letter of een symbool is, totdat je een ] tegen komt. Deze neem je al groep in een backreference (nummer 1) en dan neem je alle tekst wat volgt todat je terug een [ tegenkomt. Nu vul ik de backreference in en neem tot het eind waar ik terug een ] tegenkom. Op basis hiervan wil ik gaan splitsen.

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Wat gaat er fout met je code? Wat er zo te zien meteen al misgaat is dat je eist dat er na de [ whitespace komt. Die is er niet. Wat \p{Punct} moet doen, geen idee.

Je zoekt iets van
code:
1
\[(.*?)\](.*)\[\1\]

of, iets specifieker:
code:
1
\[([a-z][a-z0-9_]*)\](.*)\[\1\]

maar dan moet je zelf nog even de goede escapings voor java uitzoeken. De grap is dat je *? als non-greedy match gebruikt in plaats van je [^\]].

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Geen idee wat je wilt eigenlijk :) Kunnen tags genest worden? Wat wil je precies terug hebben? Java's split retourneert gewoonlijk niet wat gematched wordt, dus alles matchen lijkt me niet handig. En ik heb het idee dat je de eerste tag niet goed matched (een gekke 2e bonusgroep, plaats * is fout, etc.).

Je zou de volgende code eens kunnen proberen. Vooral de foutafhandeling is erg goed :+
Java:
1
String[] result=input.substring(1).split("[\\][]+");

(ongetest natuurlijk)
of probeer deze magic box:
Java:
1
String[] result=input.split("(?<=\\])|(?=(?<!^)\\[)");

Of kijk eens in de documentatie naar wat je moet gebruiken en leer regexp.

@ValHallASW: \p{Punct} is punctuatie en tussen de tags greedy matchen lijkt me niet handig.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
pedorus schreef op donderdag 10 juli 2008 @ 17:09:@ValHallASW: \p{Punct} is punctuatie en tussen de tags greedy matchen lijkt me niet handig.
Wat is er mis met tussen de tags greedy matchen? De enige eis is dat de laatste data in de string gelijk is aan de eerste.

[tag] kijk, voorbeeldje met [tag][tag]
moet teruggeven: 'tag': 'kijk, voorbeeldje met [tag]'
en niet: 'tag': 'kijk, voorbeeldje met'

waardoor je dus wél greedy moet matchen.

Verwijderd

Simpelweg niet met regex oplossen dit. Een simpele stack waar je elementen op pushed is vele malen eenvoudiger en je krijgt nog eens gratis validatie ook.

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Verwijderd schreef op donderdag 10 juli 2008 @ 17:27:
Simpelweg niet met regex oplossen dit. Een simpele stack waar je elementen op pushed is vele malen eenvoudiger en je krijgt nog eens gratis validatie ook.
Dan mag je mij uitleggen waarom dat eenvoudiger is? Er is géén sprake van geneste elementen dus een stack is zinloos. Daarnaast is er geen onderscheid tussen start- en eindelement, waardoor je die achteraf nog moet zitten vergelijken.

Ohja, BNF-proposal:
code:
1
2
3
4
5
<line> ::= <tag> <text> <tag>
<tag> ::= '[' <var> ']'
<var> ::=  [a-zA-Z] <varfollowchars> | [a-zA-Z]
<varfollowchars> ::= [a-zA-Z0-9_] | [a-zA-Z0-9_] <varfollowchars>
<text> ::= .*

BNF met regexps ja... je mag ze ook uitschrijven :p

dan moet je daarmee gaan parsen, de tags op een stack gooien en dan ook nog eens gaan vergelijken. Dan mag je mij uitleggen waarom dat simpeler is dan de regexp hierboven...

Verwijderd

Nou heel simpel: omdat ik niet helemaal opgelet heb :)
Pagina: 1