seth: RegEx schreiben lernen

Beitrag lesen

gudn tach!

Als Übung versuche ich jetzt eine RegEx zu schreiben, die Attributwerte ohne Anführungszeichen innerhalb von HTML-Tags treffen soll.

ok, das ist aber i.a.r. wirklich nur als uebung geeignet. in der praxis sollte sichergestellt sein, dass einige code-bestandteile wie javascript und sowas gar nicht erst durchsucht werden. gehen wir also von einem "gutartigen" html-dokument aus, dass wirklich nur html enthaelt und bei dem spitze klammern nur fuer tags verwendet werden. (in wirklichkeit waere es vermutlich eher so, dass bei fehlenden anfuehrungszeichen auch die wahrscheinlichkeit fuer nicht-maskierte spitze klammern innerhalb eines textes erhoeht waere.)

RegEx: (?:((?<==)[a-zA-Z0-9\_-[]]+))

wozu die aeussere klammer?

/(?:((?<==)[a-zA-Z0-9\_-[]]+))/

sollte das gleiche sein wie

/((?<==)[a-zA-Z0-9\_-[]]+)/

aber auch hier sollte noch die aeussere klammer ueberfluessig sein, weil in $& (perl) bzw. $0 (php, iirc) eh der komplette gematchte string drinsteht.

underscore (_) muss uebrigens nicht maskiert werden.
und "[" innerhalb einer zeichenklasse auch nicht.
und wenn das minus am beginn oder ende der zeichnklasse steht, muss es auch nicht maskiert werden.
also:

/(?<==)[a-zA-Z0-9_[]-]+/

sollte das gleiche sein, ist aber kuerzer und es ist besser lesbar.

Wie muss ich jetzt weitermachen, dass zwischen den Tags nichts mehr getroffen wird?

ich wuerde es nicht mittels eines einziges ausdrucks angehen. uebersichtlicher ist es, das problem zweizuteilen. da du allgemein ueber die "programmiertechnik" sprichst, nehme ich jetzt mal perl zur hand. in php kann man das vermutlich so aehnlich (bloss nicht so huebsch) bewerkstelligen.
schaue dir mal an, das \G fuer ein tolles dings ist: perldoc perlre und perldoc perlop.
bei "perlop" ist auch ein beispiel eines kleinen scanners, wie du ihn auch bauen koenntest.

eine erste loesung (nicht gucken, falls du selbst erst ueberlegen moechtest) koennte

#!/usr/bin/perl -w  
use strict;  
  
$_='<div class=foo1y id="barnn"><span class=foo1y id=bar1y>nix=barn und nix=barn</span>foonbarn</div>';  
while(/</g){  
  while(/\G[^>=]+=(?:([^" >]+)|"[^"]*")/gc){  
    print $1,"\n" if defined $1;  
  }  
}

sein.

prost
seth