Toon posts:

[Reguliere Expressie] Controleren of iets niet voor komt.*

Pagina: 1
Acties:
  • 131 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik kon nergens een voorbeeldje vinden die liet zien of dit kan maar kon ook niet expliciet vinden dat het dat het onmogelijk is. Denk dat ik waarschijnlijk van jullie krijg te horen dat het niet mogelijk is, maar wilde het even zeker weten.

Ik heb een tooltje waarmee ik reguliere expressies kan los laten op strings.
Nu wil ik ook met een reguliere expressie kunnen zoeken of er string NIET in staat i.p.v. wel.

normaal gesproken geef je een expressie op als:
.*ABC.*
(true als ABS gevonden is in de string).

nu wil ik dit ook andersom controleren (zonder dat ik een vinkje in mijn tool hoef te maken waarbij ik zeg geef nu true als het er niet in staat)
dus iets van:
.*!(SKIP).* (geen goede reguliere expressie)
(true als SKIP niet in de string staat)

of een ander voorbeeldje:
.*ABC.*!(SKIP).* (geen goede reguliere expressie)
(true als ABC in de string staat en niet wordt gevolgt door SKIP)

Is het mogelijk om zoiets dit te doen met reguliere expressie?

  • creative8500
  • Registratie: September 2001
  • Laatst online: 03-01 16:54

creative8500

freedom.

^ is not, maar je kunt toch ook gewoon doen:
code:
1
if (!ereg (/* blabla*/)) { }

Verwijderd

Topicstarter
creative8500 schreef op 29 december 2003 @ 15:59:
^ is not, maar je kunt toch ook gewoon doen:
code:
1
if (!ereg (/* blabla*/)) { }
Bedankt voor je snelle reply!
Ik weet dat ^ not is maar dat geld toch alleen voor een enkele karakter zoals bijvoorbeeld:
.*abc[^d].*
die elke string accepteerd waarin abcX voorkomt waar X!=D.
Maar je kan ^ toch niet gebruiken voor een string (en zeker niet op onbepaalde postitie) .*abc[^(.*SKIP.*)] of iets degelijks. Of wel?

Ik weet dat ik simpel een ! voor mijn if-je kan zetten. Maar ik wil eigenlijk gewoon een programma hebben waar ik hier niet op hoef te checken met een bijvoorbeeld een vinkje. Omdat ik op diverse in mijn tooltje reguliere expressie ingevoerd kunnen worden en op diverse plaatsen in mijn code hierop gechecked word, daarom de vraag of dit kon voordat ik mijn code ga opbouwen / uitbreiden.

Het gaat trouwens om een reguliere expressie in Java (niet java script), weet niet of dit iets uitmaakt.

[ Voor 8% gewijzigd door Verwijderd op 29-12-2003 16:14 ]


  • creative8500
  • Registratie: September 2001
  • Laatst online: 03-01 16:54

creative8500

freedom.

drm: ik zeg al niets meer :X :o

[ Voor 78% gewijzigd door creative8500 op 29-12-2003 16:28 ]


Verwijderd

Topicstarter
creative8500 schreef op 29 december 2003 @ 16:13:
Mijns inziens is er echt geen andere oplossing. :)
Ja dat vermoede ik al :( Vond het al te verdacht dat ik nergens een voorbeeldje kon vinden waar ze zoiets deden. Maar wil het gewoon even zeker weten, voordat ik aan het werk ga.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

creative8500:
Mijns inziens is er echt geen andere oplossing. :)
Een hele hoop anderens inziens wel.
Wat je nodig hebt heet "lookahead assertions". [google=Regular expressions negative lookahead assertions] ;)

edit:
ook even topictitle fixed

[ Voor 7% gewijzigd door drm op 29-12-2003 16:22 ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 12:46

crisp

Devver

Pixelated

zoiets gaat toch niet werken hoor:

code:
1
/^.*(?!blaat)$/


ik denk dat je best wel ranzige constructies moet gaan maken...

edit - zoiets dus:
code:
1
/^([^b]|b(?!laat))*$/

[ Voor 52% gewijzigd door crisp op 29-12-2003 16:34 ]

Intentionally left blank


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

crisp: afkijker ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

crisp:
ik denk dat je best wel ranzige constructies moet gaan maken...
Dat denk ik ook, maar 't ging mij er even om dat er meer is dan je in de meeste standaard regexjes ziet staan :)

Overigens is het meest logisch om het wel of niet matchen van iets niet af te laten hangen van de regex zelf maar van wat er mee gedaan wordt imho. Dus gewoon
code:
1
if ( match )
en
code:
1
if ( no match )

Wel een "vinkje" zou dus mijn keuze zijn.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Topicstarter
Bedankt drm en oisym de links waren erg hulp vol.
En heb nu al bijna voor elkaar wat ik wil. Maar loop nog tegen 1 (vreemde) beperking op:

Als ik zoek bijvoorbeeld:
.*ABC(?!.*SKIP.*).* (true als tekst ABC bevat en SKIP er niet op volgt, CORRECT!)

Maar als ik gewoon wil zoeken of SKIP niet in de tekst staat ongeacht wat er dan ook wel voor of nakomt, kan ik dit weer niet opgeven:
.*(?!.*SKIP.*).* of .*(?!SKIP).* Geeft deze true in elke wilkeurig string.
of
(?!.*SKIP.*) Geeft bij geen enkele string true, dit is logisch.

Wat zie ik over het hoef om toch een reguliere expressie true laten gegeneren in geval dat er geen SKIP in voorkomt ongeacht wat er verderrest in staat?

Ow ik was te vroeg crisp geeft me eigenlijk al het antwoord (kreeg even een telefoontje tijdens het tikken). Ga meteeen even je ranzige construtie proberen })

[ Voor 11% gewijzigd door Verwijderd op 29-12-2003 17:12 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Aragorn123:
.*(?!.*SKIP.*).* of .*(?!SKIP).* Geeft deze true in elke wilkeurig string.
Dat is ook niet zo gek, want op die manier is er altijd een plekje te bedenken in de string waarop de regex wel matcht.

Overigens, in de categorie ranzige oplossingen, vind ik deze toch iets eleganter dan die van crisp .oisyn... Dan hoef je in ieder geval niet in de string te gaan zitten knippen.
code:
1
/^(.(?!SKIP))*(?<!SKIP)$/

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Of natuurlijk gewoon de lookahead variant:
code:
1
/^(?!SKIP)(.(?!SKIP))*$/

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Topicstarter
Ik snap toch nog niet helemaal hoe die look-aheads in elkaar zitten.

Maar die ranzige constructies lijken niet te werken.
/^(.(?!SKIP))*(?<!SKIP)$/
/^(?!SKIP)(.(?!SKIP))*$/
(lijken nooit true te geven)
defineer is ze zo:
.*(.(?!SKIP))*(?<!SKIP).*
.*(?!SKIP)(.(?!SKIP))*.*
(geven ze altijd true)

Ik moet zeggen dat ik denk dat ik het nog niet helemaal snap.

Waarschijnlijk ligt heeft het te maken met mijn volgende constatering:

.*[A-H](?!.*SKIP.*).* (true als SKIP gevolgt word door letter A-H)
.*[A-I](?!.*SKIP.*).* (geeft altijd true ongeacht of SKIP in de tekst staat, waarschijnlijk omdat de I ook in SKIP voorkomt)

Is het dus toch niet mogelijk (in Java 1.4.2 met String.Match())? Of begrijp ik jullie niet goed en snap ik er nog te weinig van?

[ Voor 5% gewijzigd door Verwijderd op 30-12-2003 11:19 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Aragorn123:
Ik snap toch nog niet helemaal hoe die look-aheads in elkaar zitten.

Maar die ranzige constructies lijken niet te werken.
/^(.(?!SKIP))*(? /^(?!SKIP)(.(?!SKIP))*$/
Die lookbehind werkt inderdaad niet zoals 't zou moeten, want die matcht ook als er SKIP aan het begin van de string staat. Ook logisch trouwens.

Maar die Lookahead versie werkt echt wel hoor, probeer maar:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$array = array (
   "Hier staat SKIP in",
   "Hier staat 't niet in",
   "SKIP aan het begin",
   "Hier aan het eind: SKIP",
   "SKIP"
);

echo '<pre>';
foreach ( $array as $element ) {
   printf ( "%-30s %s\n", 
      $element,
      preg_match ( '/^(?!SKIP)(.(?!SKIP))*$/', $element )
         ? '<span style="color:#00f">Match</span>'
         : '<span style="color:#f00">No match</span>'
   );
}
echo '</pre>';



edit:

Is het dus toch niet mogelijk (in Java 1.4.2 met String.Match())? Of begrijp ik jullie niet goed en snap ik er nog te weinig van?
Mja, ik weet niet of de java implementatie die lookaheads en -behinds wel ondersteunt... Dat zou je even in de documentatie na moeten gaan.


Overigens, wat die regex feitelijk doet is het volgende:
code:
1
2
3
4
5
6
7
8
9
/
   ^               # begin van de string
   (?!SKIP)        # aan het begin mag geen SKIP staan
   (
      .            # elke character
      (?!SKIP)     # mag geen SKIP achter staan
   )*              # herhaal 
   $               # tot aan het eind van de string
/x


Overigens moet je, als je over meerdere regels wilt matchen, misschien ook wel de 's' modifier opnemen. Maar dat hangt echt af van de implementatie ervan dus je zult de docs er even op na moeten slaan.

[ Voor 36% gewijzigd door drm op 30-12-2003 11:59 ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Verwijderd schreef op 29 december 2003 @ 15:57:
Is het mogelijk om zoiets dit te doen met reguliere expressie?
Volgens mij zijn reguliere expressies daar niet voor gemaakt, omdat over het algemeen een verzameling die niet aan zo'n criteria voldoet oneindig is.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

sinaasappelsap:
Volgens mij zijn reguliere expressies daar niet voor gemaakt, omdat over het algemeen een verzameling die niet aan zo'n criteria voldoet oneindig is.
Dat het er niet voor bedoeld is ben ik wel met je eens, maar je argumentatie raakt imo kant noch wal. In de meeste gevallen zal de "oplossingsverzameling" van een regex oneindig zijn. Denk aan bijvoorbeeld het matchen van een emailadres...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Juup
  • Registratie: Februari 2000
  • Niet online
Ik had in het begin van mijn regex leren ook veel van deze kronkels in m'n hoofd. Uiteindelijk moet je eigenlijk je denken aanpassen aan de kracht van de regexps. Wat jij wil kan natuurlijk heel makkelijk zo geschreven worden:
Perl:
1
2
3
4
5
my $string = 'Apple pear banana';
if (($string =~ m/ABC/) && ($string !~ m/SKIP/))
{
  print "The string contains ABC but not SKIP.\n";
}

Moraal: vaak kun je door aanpassen van de code iets heel makkelijk bereiken. (soms ook niet ;-)

[ Voor 5% gewijzigd door Juup op 31-12-2003 12:08 ]

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Verwijderd

Topicstarter
Bedankt, vooral ook drm voor je uitgebreide uitleg. Het even erg druk gehad vandaar dat ik zo laat pas reply. Het is me een stuk duidelijker geworden hoe die RE's werken. Heb mijn code toch maar aangepast met vinkjes om aan te geven dat je zoekt of RE er wel of niet in staat. Is toch een veel duidelijker dan zo'n "ranzige" constructie. Maar wel handig dat ik nu weet dat het wel kan!

[ Voor 17% gewijzigd door Verwijderd op 06-01-2004 14:53 ]

Pagina: 1