[php] Regular Expressions

Pagina: 1
Acties:

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Ik zoek de re die een stuk tekst kan pakken uit een string die er zo uit kan zien:

1. 'dit is een tekst'
2. 'dit is een tekst <b>met een html-tag</b>'

In beide gevallen moet de re de tekst dit is een tekst kunnen matchen.

Wat ik nu heb is dit:
code:
1
\'(.*?)[\'|<b>]

Dus de re zoekt vanaf de eerste ' tot de volgende ' of <.
Helaas werkt dat niet... Ook al is .*? niet greedy, toch wordt HEEL de string gepakt. Ik zit er nu al een tijdje mee te hengelen en heb een zooitje RE-sites er op nagekeken ([url="http://google"]google[/url]), maar zonder succes.

Wat is de juiste Regular Expression?

[ specs ] [ Tweaker gallery ]


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
code:
1
\'(.*?)[\'|<b>]

[...] is een character class, zodat ie nu of ' of | of < of b of > matched. Dat lijkt me niet echt de bedoeling
code:
1
'(.*?)(<b>.*</b>)?'

ofzo moet je volgens mij hebben

[edit]* moet wel non-greedy zijn

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Ja, dat wou ik net toevoegen - non-greedy. Maar toch heeft het niet het desired effect: nu wordt er niks gematched. Je hebt inderdaad gelijk dat [...] een character class is, dus dan zou iets als
code:
1
'(.*?)['|<]

toch voldoende moeten zijn? (de \ voor de ' kan ook weg, om het wat simpeler te maken).

't Is een vraag, maar het antwoord is nee. De re pakt nog steeds HEEL de string! |:(

Volgens mij gaat jouw RE er van uit dat er ALTIJD een tag in de string staat. Of vergis ik me nu? :? Maar dit is dus niet het geval. Soms wel een tag, soms niet.

[ specs ] [ Tweaker gallery ]


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
vaag! dit werkt bij mij:
code:
1
2
3
4
5
6
<?
    $string = "'dit is een test <b>bla bla bla</b>'";
    $regex = "_'(.*?)(<b>.*</b>)?'_";
    
    echo preg_replace($regex, "\\1", $string);
?>

maar waarom gebruik je ['|<'] ? dus die |? de syntaxis van een character class is namelijk gewoon [abc] == (a|b|c)

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Hmm, je hebt gelijk. :) Ik heb het even getest en 't klopt.
Ik zie ook al waar 't fout gaat. Die teksten die ik gaf waren een voorbeeld, blijkbaar niet representatief genoeg. Er staan zulke tags in de string:

<\/b>

Dus escaped. Daar blijft-ie op hangen. Die tekst ziet er dus bv. zo uit:

'dit is een tekst <b>met een html-tag<\/b>'

[ specs ] [ Tweaker gallery ]


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
die regex (die je ondertussen alweer verwijderd hebt ;)) zou volgens mij helemaal niet moeten werken omdat je / als delimiter gebruikt, en ook bij /b> :?

[edit]
dit werkt bij mij:
code:
1
$regex = "_'(.*?)(<b>.*<\\\\/b>)?'_";

1 keer \ ge'escaped voor PHP, en 1 keer voor de regex (lekker omslachtig :))

  • tomato
  • Registratie: November 1999
  • Niet online
Op maandag 15 oktober 2001 23:31 schreef marcusk het volgende:
de syntaxis van een character class is namelijk gewoon [abc] == (a|b|c)
Het resultaat is weliswaar hetzelfde, maar denk eraan dat je beter een character class gebruikt dan alternation.
Ten eerste zorgt alternation voor erg veel backtracking wat slecht is voor de performance. Ten tweede werken de alternation parentheses ook als capturing en grouping parentheses. Beide punten zorgen voor extra overhead.Dus als je een alternation als character class kunt schrijven en je hebt de capturing niet nodig, gebruik dan een character class (de grouping houd je gewoon, of heb je eigenlijk niet meer nodig, dus daar hoef je het niet voor te laten). Met gratis versimpelde verklaring ;)

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Er ging wat mis met de edit. stukkie code moest niet weg. Hoe dan ook, nee dit werkt niet. Krijg weer heel de string terug. 'k Zit er ook mee te klooien, want je eerste... nouja tweede suggestie werkte wel. Zodra die backslash erbij komt kijken werkt het niet meer goed.

[ specs ] [ Tweaker gallery ]


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Op maandag 15 oktober 2001 23:49 schreef tomato het volgende:
Het resultaat is weliswaar hetzelfde, maar denk eraan dat je beter een character class gebruikt dan alternation.
dat heb ik idd gelezen uit 'dat boek', maar dit was om het ff simpel uit te leggen :) (bedankt nogmaals voor die link, is erug leerzaam! :))

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
marcusk:
dit werkt bij mij:
code:
1
$regex = "_'(.*?)(<b>.*<\\\\/b>)?'_";

1 keer \ ge'escaped voor PHP, en 1 keer voor de regex (lekker omslachtig :))
Yesss! Ik was ook al met die \\\ in de weer - volgens mij was ik bij 3 blijven plakken - hoe dan ook, 'k kreeg 'm niet. Deze werkt! :9 Thanks!

tomato: Volgens mij zit er geen alternation meer in bovenstaande regex. Kan je 'm nog optimaliseren? 8-)

[ specs ] [ Tweaker gallery ]


  • tomato
  • Registratie: November 1999
  • Niet online
Op maandag 15 oktober 2001 23:52 schreef marcusk het volgende:
dat heb ik idd gelezen uit 'dat boek', maar dit was om het ff simpel uit te leggen :) (bedankt nogmaals voor die link, is erug leerzaam! :))
No thanks ;)
Geweldig boek ja :9
Op maandag 15 oktober 2001 23:45 schreef marcusk het volgende:
code:
1
$regex = "_'(.*?)(<b>.*<\\\\/b>)?'_";
Probeer toch nog kleine verbetering te vinden :P
code:
1
/'([^']+?)(<b>[^']+)?'/is

  • tomato
  • Registratie: November 1999
  • Niet online
Op maandag 15 oktober 2001 23:56 schreef Explore het volgende:
tomato: Volgens mij zit er geen alternation meer in bovenstaande regex. Kan je 'm nog optimaliseren? 8-)
Bij deze 8-)
Maar ik zou even goed na moeten denken om echt te optimaliseren en om na te gaan of alle dingen die ik nu veranderd heb wel echt 'beter' zijn (.* is evil).

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Op dinsdag 16 oktober 2001 00:06 schreef tomato het volgende:

[..]

Bij deze 8-)
Maar ik zou even goed na moeten denken om echt te optimaliseren en om na te gaan of alle dingen die ik nu veranderd heb wel echt 'beter' zijn (.* is evil).
Nifty :) Die werkt ook. Alleen vat ik 'm nu niet meer. Hoe moet je 'm bv. aanpassen als je volgorde van de <b> en <\/b> is omgewisseld in de string?

[ specs ] [ Tweaker gallery ]


  • tomato
  • Registratie: November 1999
  • Niet online
Op dinsdag 16 oktober 2001 00:15 schreef Explore het volgende:
Nifty :) Die werkt ook. Alleen vat ik 'm nu niet meer. Hoe moet je 'm bv. aanpassen als je volgorde van de <b> en <\/b> is omgewisseld in de string?
Ik ging er nu dus vanuit dat er altijd correcte HTML is (of dat je iig wilt stoppen bij iedere <b>, ook als er geen </b> volgt voor de sluitende ').
Als je wilt stoppen bij een </b> ipv bij een <b> vul je die in ipv de <b> lijkt me? Of snap ik je niet helemaal?

[edit]
Maar <b> en </b> omwisselen maakt toch geen sense :?

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
tomato:
Maar <b> en </b> omwisselen maakt toch geen sense :?
Dat lijkt maar zo. :) Maar thanks anyway! Ik heb voor elkaar wat ik probeerde te bereiken. :9

[ specs ] [ Tweaker gallery ]

Pagina: 1