Laden...

RegEx kürzester Match [und die Gefahren von .*?]

Erstellt von rollerfreak2 vor 14 Jahren Letzter Beitrag vor 14 Jahren 5.350 Views
rollerfreak2 Themenstarter:in
916 Beiträge seit 2008
vor 14 Jahren
RegEx kürzester Match [und die Gefahren von .*?]

Hallo zusammen, ich habe eine Problem mit einem Regex Pattern. Und zwar will ich sowas

<td id="fett"><a name="1481">03.08.2009</a><br></td>

Daraus soll sowas werden

<td><a>03.08.2009</a><br></td>

Das Problem ist der kürzeste RegEx.

Zum Beispiel: Regex=<td.{0,15}>
Da ist das Problem das er immer den längsten Match nimmt. Das ist in meinem Fall ja aber falsch. Ich möchte also nach einem < suchen, dann beliebig viele Zeichen, jedoch kommt dann ein > soll das Pattern matchen, daher > muss exkludiert werden von den eigentlich beliebigen Zeichen. Ich bekomme den Ausdruck aber leider nicht hin.

Hilfe

Again what learned...

rollerfreak2 Themenstarter:in
916 Beiträge seit 2008
vor 14 Jahren

Ich glaub ich habs, muss es zwar noch verifizieren aber das müsste funzen.

<[^<]*>

Problem ist das gierige und genügsame Verhalten. Kann das eventuell noch jemand bestätigen. Habs kurz mit dem RegexLab getestet, und scheint zu funzen.

Again what learned...

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo rollerfreak2,

EDIT: Ah, wer lesen kann, ist klar im Vorteil. Du willst einfach nur auf einen Tag matchen.
Wie schon bemerkt, ist das Problem das gierige Verhalten. Folgendes reicht schon aus (genügsames Verhalten durch Fragezeichen "einschalten"):

<.*?>

Gruß,
dN!3L

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo dN!3L,

im Allgemeinen ist jedoch eine Negation sicher als das Fragezeichen.

Hier wäre das: <[^>]*>

herbivore

rollerfreak2 Themenstarter:in
916 Beiträge seit 2008
vor 14 Jahren

Es gehen beide, wobei ich dem mit der negation einfacher zu lesen finde. Das Fragezeichen schaltet das genügsame Verhalten ein, ist aber schwerer zu lesen.

ps.: Hatte mich oben nur vertippt.

<[<]*> sollte natürlich <[>]*> sein.

Danke an euch beide.

Again what learned...

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo herbivore,

im Allgemeinen ist jedoch eine Negation sicher als das Fragezeichen.

Hm, warum? Hast du mal ein Beispiel? Bzw. was verstehst du unter "Sicherheit"?

Btw.:*<[^<]*> matched:
<td <id="fett">:::

Gruß,
dN!3L

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo dN!3L,

Hast du mal ein Beispiel?

nimm an, du suchst alle Tags, die mit /> abgeschlossen sind. Wenn man dafür das Fragezeichen benutzt, also <.*?/> dann passt das fälschlich auch auf <b>Wichtig</b><br />, matcht also über mehrere Tags hinweg und nicht nur auf <br />, wie das beabsichtigt und bei <[^>]*/> auch der Fall wäre.

Das Fragezeichen sorgt also inbesondere nicht dafür, dass ein Match später beginnt, damit er (noch) kürzer wird. Auch bei Fragezeichen beginnt der Match immer - wie bei Regex üblich - so weit links wie möglich.

Oder anders gesagt, das Fragezeichen macht den Match nicht automatisch so kurz, wie man das erwartet oder sich das wünscht. Man kann da leicht reinfallen.

Btw.:

Mal abgesehen davon, dass <[^<]*> ja nicht Absicht, sondern ein Tippfehler war, ist <td <id="fett"> kein syntaktisch korrektes Html. Insofern finde ich es korrekt, dass das Tag nicht richtig erkannt wird. Außerdem kann man diesen Fall durch <[^<>]*> leicht in den Griff bekommen, indem man sowohl schließende als auch öffnende spitze Klammern ausschließt.

herbivore

PS: Wenn man nicht nur ein einzelnes Zeichen ausschließen will (im Beispiel die spitze Klammer zu), sondern eine ganze Zeichenfolge, dann muss man zu negativen Lookaheads greifen.

Mit ((?!hallo).)* findet man einen beliebigen Text, aber nur solange bis das Wort hallo auftaucht. Mit <ul>((?!</?ul>).)*</ul> findet man die zusammengehörigen Tags der (innersten) Bullet-Liste.

Suchhilfe: 1000 Worte, Regex, gierig, Gefahr, gefährlich

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo herbivore,

Oder anders gesagt, das Fragezeichen macht den Match nicht automatisch so kurz, wie man das erwartet oder sich das wünscht. Man kann da leicht reinfallen.

Ah OK, einleuchtend. Danke für das Beispiel. =)

Beste Grüße,
dN!3L