[Java] Regex bepalen

Pagina: 1
Acties:

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Ik krijg het niet helemaal voor elkaar om een bepaalde regex te bepalen op een String, zodat deze juist gevalideerd kan worden. Ik dien alle woorden te filteren die beginnen of eindigen met een / én er mag geen // in het gehele woord voorkomen.

tot hiertoe had ik:
code:
1
^(/)|(//)+|$(/)

Maar dit lijkt enkel maar de starting/trailing slash te detecteren.

edit:
idd, was een typo

[ Voor 5% gewijzigd door -FoX- op 05-07-2006 15:21 ]


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 12-02 12:22
Gaat sowieso al raar, je wilt matchen op eem '/' met vervolgens een regel begin. Daar zal geen enkele sinlge line string op passen.

Je match lees ik als volgt:
/ met daarna een regel begin

OF

// 1 of meer keer

OF

/ met direct een regeleinde

Daar match je dus op.

Ik zou eerder denken aan iets als:
code:
1
^[^/].*|^.*[^(//)].*$|.*[^/]$


Dus:
Regelbegin met vervolgens NIET een '/' en vervolgens willekeurige karakters (let op, volgens mij matched een lege string hier ook niet op)

OF

Regelbegin dan willekeurige karakters geen '//' en weer willekeurige karakters en een regeleinde.

OF

willekeurige karakters, geen '/' en dan een regeleinde.

Ik weet even niet of [^/] ook op een leeg (geen) karakter matched, kan zijn dat je namelijk niet kan matchen op een lege string.

[ Voor 39% gewijzigd door The - DDD op 05-07-2006 15:21 ]


  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Dit werkt voor de meeste gevallen (beginnende met /, in het midden een '//', op 't einde een /). Maar woorden waarin ergens in het midden een '/' staat, worden niet juist gevalideerd.
code:
1
^ [ /].*|^.*[(//)].*$|.*[ /]$


Dit is overigens vrij simpel op te lossen door volgende regex te gebruiken:
code:
1
^ [ /].*|^.*(//).*$|.*[ /]$

De '[' ']' zorgen er namelijk voor dat van / tot / geëvalueerd wordt, waardoor ook woorden met een single / niet geldig gevonden worden.

[ Voor 49% gewijzigd door -FoX- op 05-07-2006 15:42 ]


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 12-02 12:22
Weet je het zeker? Want de '^' binnen de blokhaken zorgt in mijn regex namelijk voor een negatie. Dus een match heeft NIET een slash aan het begin of NIET een dubbele slash waar dan ook OF niet een slash aan het einde.

Edit: merk nu dat negatie alleen binnen character classes werkt... ;(

Je zult dus inderdaad de strings moeten matchen die je niet wil.

Edit2:
Zoiets dus:
code:
1
^/.*|.*/{2}.*|.*/$


Dit matched op alle dubbele slashes of een begin of een eind slash. Als dat spul allemaal niet er in mag zitten, checken en als het true oplevert, dan moet je een foutmelding geven.

[ Voor 54% gewijzigd door The - DDD op 06-07-2006 00:54 ]


Verwijderd

voorzover ik uit je startpost begrijp heb je 2 mogelijkheden, een woord beginnend met een / of eindigend met een /.
in het woord zelf mag geen // voorkomen, maar verder is alles toegestaan, een enkele / is ook toegestaan?
en je hebt het over een woord, maar gebruikt zinnen, ^ en $, moeten dat geen whitspaces \w zijn?

anders denk ik dat dit het wel doet:
code:
1
(^/[^(//)]$)|(^[^(//)]/$)

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:11

crisp

Devver

Pixelated

code:
1
[^(//)]

Zo werken character-classes natuurlijk niet ;)
Je zal eerder in deze trant moeten denken:
code:
1
([^/]|/(?!/))*

oftewel: met assertions werken. Ook voor het bepalen of iets een 'woord' is zal je de boundaries moeten checken; ofwel met een look-behind of met een non-matching subpattern:
code:
1
(?<=^|\s)

vraag is of wellicht andere karakters dan whitespace ook een boundary kunnen zijn (leestekens?)

Intentionally left blank


  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Het doel is eigenlijk om internationale financiële formaten te valideren op correctheid; dus eigenlijk mogen er ook geen whitespaces of overige karakters voorkomen in het formaat.

De negatie moet ook niet gemaakt worden, aangezien ik deze regels check op onjuistheid. Dus in het geval van een onjuiste string dient de juiste exception opgeworpen te worden.

Voorlopg gebruik ik deze check voor het '/' begin-einde en '//' midden probleem.
Java:
1
String regex = "^[ /].*|^.*(//).*$|.*[ /]$";


Voorbeelden van ongeldige formaten:
code:
1
2
3
4
5
/1234567890
1234567890/
12345//6789
1234  67890
123?567890


@crisp; kan je even verduidelijken?

[ Voor 12% gewijzigd door -FoX- op 06-07-2006 11:58 ]


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 13-02 20:06

Gerco

Professional Newbie

Dit lijkt me het makkelijkst te doen door die // requirement gewoon op te lossen met een String.indexOf() en de rest met een regex te doen:
Java:
1
  return formaat.indexOf("//")==-1 && formaat.matches("^[^/][^\s\?]*[^/]$");


Waarbij "[^\s\?]*" uiteraard nog uitgebreid moet worden met de rest van de verboden karakters.

[ Voor 37% gewijzigd door Gerco op 06-07-2006 12:05 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:11

crisp

Devver

Pixelated

En heb je ook nog wat voorbeelden van juiste formaten? Praten we hier nu over woorden of over getallen?
Uiteindelijk krijg je dus een 'zin' en die moet afgewezen worden op het moment dat daar een 'woord' in staat dat niet voldoet aan bepaalde syntax? Wellicht is het dan handiger om die 'zin' op te breken in 'woorden' en vervolgens te kijken of al die 'woorden' wel syntactisch correct zijn (al dan niet met reguliere expressies).

[ Voor 7% gewijzigd door crisp op 06-07-2006 12:06 ]

Intentionally left blank


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 12-02 12:22
crisp schreef op donderdag 06 juli 2006 @ 11:44:
code:
1
[^(//)]

Zo werken character-classes natuurlijk niet ;)
Je zal eerder in deze trant moeten denken:
code:
1
([^/]|/(?!/))*

oftewel: met assertions werken. Ook voor het bepalen of iets een 'woord' is zal je de boundaries moeten checken; ofwel met een look-behind of met een non-matching subpattern:
code:
1
(?<=^|\s)

vraag is of wellicht andere karakters dan whitespace ook een boundary kunnen zijn (leestekens?)
Enig idee waar een goede uitleg is te vinden over look ahead en look behind? Heb met die regex constructie in Java nog altijd een beetje moeite. |:( Moet toch is anders worden.

Edit, dit helpt allicht: http://www.regular-expressions.info/lookaround.html

[ Voor 7% gewijzigd door The - DDD op 06-07-2006 13:05 . Reden: Zelf 1 linkje gevonden. ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:11

crisp

Devver

Pixelated

The - DDD schreef op donderdag 06 juli 2006 @ 13:01:
[...]
Enig idee waar een goede uitleg is te vinden over look ahead en look behind? Heb met die regex constructie in Java nog altijd een beetje moeite. |:( Moet toch is anders worden.
Persoonlijk gebruik ik altijd de PHP PCRE-reference; ik neem aan dat de implementatie in Java niet alteveel afwijkt (hoewel ondersteuning voor look-ahead, look-behind e.d. nog wel eens wil ontbreken in bepaalde talen; zelfs de ungreedy-modifier wordt niet overal ondersteund).

Ik denk echter steeds meer dat het probleem van de topicstarter wellicht beter niet puur met een reguliere expressie zou moeten worden opgelost.

Intentionally left blank


  • deDorus
  • Registratie: Augustus 2001
  • Laatst online: 09-02 09:20

deDorus

Meisje, ik ben een C-man...

Erg handig voor het doorgronden van regular expressies:
http://www.weitz.de/regex-coach

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 12-02 12:22
Java is Perl 5 compatible op een paar verschillen na. Ook moet je je voor sommige constructies helemaal suf escapen in Java. Vaak is het dan makkelijker om de regex in te lezen vanuit een properties file.

http://java.sun.com/j2se/...a/util/regex/Pattern.html

Verwijderd

Maar waarom wil eigenlijk je dit met regex op te lossen? Dit gaat toch prima met een relatief simpel, en vele malen leesbaarder loopje?

Regex wordt de laatste tijd mijns inziens veel te veel misbruikt.

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Verwijderd schreef op donderdag 06 juli 2006 @ 16:48:
Maar waarom wil eigenlijk je dit met regex op te lossen? Dit gaat toch prima met een relatief simpel, en vele malen leesbaarder loopje?

Regex wordt de laatste tijd mijns inziens veel te veel misbruikt.
Inderdaad, kan. Maar waarom hier gen regex voor gebruiken? Het was ook simpelweg op te lossen door:
Java:
1
2
3
4
5
boolean match = false;
if (test.indexOf("//") > 0)
    match = true;
if (test.indexOf("/") == 1 || test.lastIndexOf("/") == test.length())
    match = true;

Maar ik hoor ze binnenkort al afkomen dat er wijzigingen aan moeten gebeuren e.d. en als het dan maar op 1 simpele string aangepast moet worden in een config file, is dat vele malen makkelijker dan opnieuw te compileren/distributen/...

edit:
Ohja, het plain java voorbeeld is trouwens zo'n 30x sneller bij 1miljoen operaties :P

[ Voor 9% gewijzigd door -FoX- op 06-07-2006 17:16 ]


  • NLChris
  • Registratie: Juli 2004
  • Laatst online: 10:11
-FoX- schreef op woensdag 05 juli 2006 @ 14:56:
Ik krijg het niet helemaal voor elkaar om een bepaalde regex te bepalen op een String, zodat deze juist gevalideerd kan worden. Ik dien alle woorden te filteren die beginnen of eindigen met een / én er mag geen // in het gehele woord voorkomen.

tot hiertoe had ik:
code:
1
^(/)|(//)+|$(/)

Maar dit lijkt enkel maar de starting/trailing slash te detecteren.

edit:
idd, was een typo
code:
1
2
if ((strInput[0] == "/") or (strInput[strInput.length] == "/") or strInput.indexOf("//"))
      valid = false;
:?

Ik zie in dit geval het nut van RegExp niet

edit:
Maar ik hoor ze binnenkort al afkomen dat er wijzigingen aan moeten gebeuren e.d. en als het dan maar op 1 simpele string aangepast moet worden in een config file, is dat vele malen makkelijker dan opnieuw te compileren/distributen/...
Ligt compleet aan het type programma, maar als de eisen kunnen veranderen is een RegExp idd een betere optie.

[ Voor 24% gewijzigd door NLChris op 06-07-2006 17:18 ]

Pagina: 1