Toon posts:

[PCRE] string herkennen met geëscapete quotes

Pagina: 1
Acties:

Verwijderd

Topicstarter
Voor een hobby-projectje ben ik bezig met een xhtml-validator (in PHP), en een belangrijk onderdeel hiervan zijn enkele regular expressions. Ik wilde per se regexp's die niet mis kunnen gaan, maar die echt overal mee rekening houden.

Ik laad de complete source van een (x)html pagina in een string, en maak hiervan een array, door preg_split() hierop toe te passen, met de PREG_SPLIT_DELIM_CAPTURE optie, zodat ook de tags in de array komen.

Stap 1 was het herkennen van xhtml-tags, de elementen zonder attributes waren natuurlijk eenvoudig te vinden. Maar toen kwamen dus die attributes. Bij xhtml moeten de values tussen dubbele quotes staan, maar een value kan ook (geëscapete) quotes bevatten. Hierdoor zou voor dat stukje het patroon /"[^"]*"/ niet voldoende zijn.

Ik concentreerde me op dat probleem met backslashes, en kwam na een hoop geprobeerd te hebben op het volgende:
code:
1
".*?(?<!\\\\)(?:\\\\{2})*"

Eenvoudig gezegd: zoek bij het vinden van een dubbele quote " naar de eerstvolgende dubbele quote, die na 0 of een even aantal backslashes moet staan. Maar ik zie liever een andere optie dan de greed veranderen. Als ik dit namelijk toepas in een grotere regular expression, gaat het daardoor alsnog niet goed.

Dit is de regexp die ik nu heb voor een xhtml-start-tag:
code:
1
/(<[a-z]+(?:\s+[a-z\-]+=".*?(?<!\\\\)(?:\\\\{2})*")*\s*>)/i

Iets als <element attribute="tekst\\"nogmeertekst"> matcht, maar dat wil ik helemaal niet. Daarom moet die regular expression op één of andere manier anders. Ik wil dus niet dat die mbv. greed de korste gequote string zoekt, ik wil eigenlijk dat er geen even aantal backslashes, gevolgd door een dubbele quote in de string mág voorkomen.

Ik heb nu al vele dingen geprobeerd, teveel op op te noemen, maar ik kom er niet uit. Ik heb niet in de manual kunnen vinden hoe je zoekt naar de langst mogelijke string, waarin een bepaald patroon niet mag woorkomen.

Is er iemand die hier een oplossing voor weet? :)

  • Grum
  • Registratie: Juni 2001
  • Niet online
ik vraag me af of dit in xhtml mag:
code:
1
attribute="tekst\\"nogmeertekst"

zou het niet iets als:
code:
1
attribute="tekst&quot;nogmeertekst"

moeten zijn ?

escapen bestaat volgens mij niet in (x)(ht)ml

  • tomato
  • Registratie: November 1999
  • Niet online
Zoek eens in wat regex topics naar posts van mij, ik heb hier al vrij vaak een aanpak hiervoor gepost.

Voorbeeldje uit mijn hoofd om een doublequoted string te matchen:
code:
1
2
3
4
5
6
7
8
9
10
11
/
   "
   (?:
    [^"\\]*
    (?:
       \\.
       [^"\\]*
    )*
   )
   "
/

Verwijderd

Topicstarter
Op donderdag 04 april 2002 18:55 schreef tomato het volgende:

Zoek eens in wat regex topics naar posts van mij, ik heb hier al vrij vaak een aanpak hiervoor gepost.

[regexp]
Bedankt! :)
Die doet inderdaad precies wat ik nodig had. Nu nog even analyseren hoe het nou precies werkt, maar dat moet wel lukken nu.

  • tomato
  • Registratie: November 1999
  • Niet online
Cheatah: Bedankt! :)
Die doet inderdaad precies wat ik nodig had. Nu nog even analyseren hoe het nou precies werkt, maar dat moet wel lukken nu.
Zie voor een uitgebreide uitleg over dit pattern 'Mastering Regular Expressions' (O'Reilly), hoofdstuk 5 'Crafting a Regular Expression'.

Kort gezegd:
code:
1
2
3
4
5
6
7
8
9
10
11
/
   "           # (1)
   (?:
    [^"\\]* # (2)
    (?:
       \\.   # (3)
       [^"\\]*   # (2)
    )*
   )
   "           # (4)
/

(1) Opening quote

(2) Alle 'normale' karakters (allesbehalve een quote of backslash)

(3) Een geescaped karakter (wat dan ook, bijvoorbeeld een quote)

(4) Closing quote


Dit zit een beetje verpakt in een 'unrolling the loop' methode zoals meneer Friedl dat in Mastering Regular Expressions noemt.

Verwijderd

Topicstarter
Op donderdag 04 april 2002 23:45 schreef tomato het volgende:

Zie voor een uitgebreide uitleg over dit pattern 'Mastering Regular Expressions' (O'Reilly), hoofdstuk 5 'Crafting a Regular Expression'.

Dit zit een beetje verpakt in een 'unrolling the loop' methode zoals meneer Friedl dat in Mastering Regular Expressions noemt.
Dat klinkt als een zeer interessant boek, daar ga ik eens naar op zoek :)

Ook je extra uitleg was zeer verhelderend, nogmaals bedankt :)

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 22:39
Grum: ge-escapete xhtml kan wel, bijvoorbeeld in javascript :o op de pagina.

  • Grum
  • Registratie: Juni 2001
  • Niet online
Dan escape je dus niet IN de xml maar in de data snuffert.

Xml is puur wat binnen de <>'s staat en niet binnen de ><'s

Nu kan dat natuurlijk wel (bij nested structures) maar dan NOG staat het binnen <>'s

ddc, you can't outsmart me :+

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 22:39
ehm:

document.write("<input type='text' value='Hier komen ddc\'s getallen' />");

:?

  • Grum
  • Registratie: Juni 2001
  • Niet online
en helaas is dat dus javascript en geen xml

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 22:39
Op vrijdag 05 april 2002 10:58 schreef Grum het volgende:
en helaas is dat dus javascript en geen xml
En nu je punt :?

[edit]
je bedoelt vast dat het binnen <script> staat...

  • Grum
  • Registratie: Juni 2001
  • Niet online
doe niet zo vervelend :+

escapen in xml bestaat gewoon niet (iig niet voor quotes)

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 22:39
Op vrijdag 05 april 2002 11:11 schreef Grum het volgende:
doe niet zo vervelend :+
>:) >:) :7

Maarre, die validator van Cheatah zal dus toch alle javascript eruit moeten filteren, anders wordt deze tag ook gewoon herkend als tag...
Pagina: 1