2008-12-14 7 views
12

Ich habe immer geschrieben reguläre Ausdrücke wie dieseRegex: Ist Faul schlimmer?

<A HREF="([^"]*)" TARGET="_blank">([^<]*)</A> 

aber ich gerade gelernt, diesen lazy thing und dass ich es wie folgt diesen zweiten Ansatz unter Verwendung eines beliebigen Nachteil

<A HREF="(.*?)" TARGET="_blank">(.*?)</A> 

ist es schreiben kann? Die Regex ist definitiv kompakter (sogar SO parst es besser).

Bearbeiten: Es gibt zwei beste Antworten hier, die zwei wichtige Unterschiede zwischen den Ausdrücken zeigen. ysths Antwort zeigt auf eine Schwäche im nicht-gierigen/faulen, bei der der Hyperlink selbst möglicherweise andere Attribute des A-Tags enthalten könnte (definitiv nicht gut). Rob Kennedy weist auf eine Schwäche des gierigen Beispiels hin, nämlich dass Ankertexte keine anderen Tags enthalten können (definitiv nicht in Ordnung, weil sie auch nicht den ganzen Ankertext erfassen würden) ... also ist die Antwort, dass reguläre Ausdrücke das sind, was sie sind sind, faule und nicht faule Lösungen, die die gleichen scheinen, sind wahrscheinlich nicht semantisch gleichwertig.

Bearbeiten: Dritte beste Antwort ist von Alan M über die relative Geschwindigkeit der Ausdrücke. Zur Zeit werde ich seine beste Antwort markieren, damit die Leute ihm mehr Punkte geben :)

+2

LOL! Danke für den Schub. –

+0

Sicher, aber wenn die Frage ein wenig älter wird, liebt es offenbar niemand mehr. –

+0

Wenn Sie die akzeptierte Antwort ändern können, zögern Sie nicht, dies zu tun. Meine Antwort beantwortete die Frage nicht wirklich, sie ging nur auf die anderen Antworten ein. –

Antwort

12

andere Sache zu prüfen ist, wie lange der Zieltext ist, und wie viel davon wird durch die quantifizierten subexpression angepasst werden. Zum Beispiel könnten Sie, wenn Sie in einem großen HTML-Dokument, versuchen das ganze < BODY> Element zu passen versuchen diesen regex zu verwenden:

/<BODY>.*?<\/BODY>/is 

Aber das wird eine ganze Menge unnötiger Arbeit zu tun, passend ein Zeichen zu einer Zeit, während effektiv ein negatives Lookahead vor jedem einzelnen stattfindet. Sie wissen, dass das </BODY> -Tag sehr nahe am Ende des Dokuments sein wird, also ist es klug, ein normales gieriges Quantitier zu verwenden; Lass es den ganzen Rest des Dokuments schlürfen und dann die wenigen Zeichen zurückverfolgen, die notwendig sind, um mit dem End-Tag übereinzustimmen.

In den meisten Fällen werden Sie keinen Geschwindigkeitsunterschied zwischen gierigen und widerwilligen Quantifizierern bemerken, aber es ist etwas zu beachten. Der Hauptgrund, warum Sie bei der Verwendung von widerwilligen Quantifizierern vernünftig sein sollten, ist der, auf den die anderen hingewiesen haben: Sie mögen es widerwillig tun, aber sie werden mehr zusammenbringen, als Sie wollen, wenn es das erfordert, um einen Gesamtwert zu erreichen Spiel.

1

"faul" ist das falsche Wort hier. Du meinst nicht-gierig im Gegensatz zu gierig. Es gibt keinen Nachteil, es zu benutzen, den ich kenne. Aber in Ihrem speziellen Fall sollte es auch nicht mehr effizient sein.

+0

Danke für Ihre Antwort. Diese Leute http://www.regular-expressions.info/repeat.html beziehen sich auf faul oder gierig, was ich zugeben, macht weniger Sinn als gierig und nicht gierig. –

+2

Es könnte Sie interessieren zu wissen, dass "diese Jungs" eigentlich Jan Goyvaerts, ein SO-Mitglied ist. ;) –

+0

Ja, ich kann mich wirklich nicht über die Qualität von SO Memebers beschweren. Das letzte Mal, dass ich ein technisches Forum mit dieser Ebene von Antworten benutzt habe, war das xSLT-Forum, und ein berühmter Guru namens David Carlile (so etwas) beantwortete die meisten Fragen persönlich. –

3

Es geht nicht um besser oder schlechter. Der Begriff, den ich am meisten gesehen habe, ist gierig vs. nicht-gierig, aber wie auch immer du sagst, sie machen zwei verschiedene Dinge. Sie möchten den richtigen für die Aufgabe verwenden. I.e. Deaktivieren Sie die Greedy-Option, wenn Sie mehrere Übereinstimmungen in einer Zeile nicht erfassen möchten.

1

Nicht gierig ist besser, nicht wahr? Es arbeitet vorwärts, sucht jedes Mal nach einer Übereinstimmung und stoppt, wenn es eine gefunden hat, während die normale Kleene-Schließung (*) rückwärts läuft, um den Rest der Eingabe zu vergleichen und Dinge zu entfernen, bis eine Übereinstimmung gefunden wird.

Am Ende machen sie verschiedene Dinge, aber ich denke, nicht-gierig übertrifft gierig. Bedenken Sie, dass ich das nicht getestet habe, aber jetzt bin ich neugierig.

+1

Wette es ist abhängig von der Implementierung. Danke für deine Antwort! –

7

Beachten Sie, dass Ihre Beispiele nicht gleichwertig sind. Ihr erster regulärer Ausdruck wird keine Verknüpfungen auswählen, die andere Tags enthalten, z. B. img oder b. Der zweite reguläre Ausdruck wird, und ich nehme an, das ist wahrscheinlich das, was Sie sowieso wollten.

Neben dem Unterschied in der Bedeutung ist der einzige Nachteil, den ich mir vorstellen kann, dass die Unterstützung für nicht gierige Modifikatoren nicht ganz so weit verbreitet ist wie die Negation der Zeichenklassen. It's more widely supported than I thought, before I checked, but notably absent from the list is GNU Grep. Wenn die von Ihnen verwendeten Evaluatoren für reguläre Ausdrücke dies unterstützen, können Sie sie verwenden.

+0

Hallo Rob, es ist wahr, ich will alles, was zwischen den A-Tags gehen kann. Ob mein Regex-Evaluator es unterstützt ... wow, ich wusste nicht einmal, dass das nicht geht. Ich muss überprüfen (ich bin in AS3) und ich werde die Frage damit bearbeiten. –

8

Die ergänzte Zeichenklasse definiert rigoroser, was Sie anpassen möchten, also wann immer Sie können, würde ich es verwenden.

Die nicht gierig regex werden die Dinge passen Sie nicht wahrscheinlich, wie wollen.

<A HREF="foo" NAME="foo" TARGET="_blank">foo</A> 

, wo Ihre erste *?

Spiele
foo" NAME="foo 
+0

Ich bekomme deine letzte Bemerkung nicht. Was würde Ihrer Meinung nach hier zusammenpassen und warum würde es anders sein als das, was wir wollen? –

+0

Ist nicht der erste. *? passen Sie so wenige Zeichen wie möglich an, bevor Sie das doppelte Anführungszeichen verwenden, also nur foo? – Kenny

+0

ysth: Ich sehe jetzt Ihren Punkt, d.h. dass die Argumente neu geordnet werden. –