2012-03-31 9 views
1

Warum ist dieser reguläre Ausdruck so faul? Es soll auf eine height/width -Eigenschaft verweisen, dazwischen (optional) und dann auf eine andere height/width-Eigenschaft (optional). Es erhält nur die erste Eigenschaft und wird dann beendet, auch wenn es mehr Übereinstimmungen gibt.Warum ist mein Regulärer Ausdruck so faul?

((?:height|width)=["']\d*["'])([\s\w:;'"=])*?((?:height|width)=["']\d*["'])? 

sample code on regexpal

+0

es sei denn, Ihre Regex macht [lazy evaluation] (http://en.wikipedia.org/wiki/Lazy_evaluation), das [tag: faul] -Tag passt hier nicht gut. –

+2

Überprüfst du alle Gruppen? Dies scheint für mich die ganze Höhe und Breite zu finden? –

+0

@BFTrick hat diese Hilfe? Hat es nichts getan? Etwas? –

Antwort

6

Der einfachste Weg, um zu sehen, was los ist in den erweiterten Format auszubrechen. Im erweiterten Format, Ihre regex ...

((?:height|width)=["']\d*["'])([\s\w:;'"=])*?((?:height|width)=["']\d*["'])? 

wird dann (mit Kommentaren, die im erweiterten Format legal sind):

(     # a group that captures... 
    (?:height|width) # Height or width 
    =     # The Equals sign 
    ["']    # a double quote or quote 
    \d*    # zero or more digits 0-9 
    ["']    # a double quote or quote 
)      # requried 
(     # zero or more groups that capture...space chars, 
    [\s\w:;'"=]  # letters, numbers, colon, quote, dobule quote, and equals 
)*?     # zero or more times, lazily (giving up as much as it can) 
(     # a group that... 
    (?:height|width) # height or width 
    =     # colon 
    ["']    # double quote or quote 
    \d*    # zero or more numbers 
    ["']    # double quote or quote 
)?     # optionally 

So kann Ihr regex 1 Gruppe erzeugen und bis zu N-Gruppen , abhängig von der verwendeten Regex-Engine. Deine letzte Gruppe wird die Gruppe sein, die du willst, wenn sie da ist. Entfernen Sie den faulen Modifikator der zweiten Gruppe (die ?) und machen die zweite Gruppe nicht-Capturing, etwa so:

(     # a group that captures... 
    (?:height|width) # Height or width (non capturing) 
    =     # The Equals sign 
    ["']    # a double quote or quote 
    \d*    # zero or more digits 0-9 
    ["']    # a double quote or quote 
)      # requried 
(?:     # zero or more groups of space chars, letters, 
    [\s\w:;'"=]  # numbers, colon, quote, dobule quote, and equals 
)*     # zero or more times as much as it can UNTIL... 
(     # a group that captures... 
    (?:height|width) # height or width (non-capturing) 
    =     # colon 
    ["']    # double quote or quote 
    \d*    # zero or more numbers 
    ["']    # double quote or quote 
)?     # optional 

und jetzt die ersten und letzten Tags werden in den Gruppen 1 und 2 werden jeweils mit der Zeug in der Mitte ignoriert. Wenn es das letzte gibt, wird es erfasst.

Hinweis: Der letzte Teil wird möglicherweise nicht erfasst, da ein Zeichen, das in der mittleren Gruppe erfasst werden muss, nicht angegeben ist. Wenn es ein Komma, ein oder eine andere Art von Markierzeichen gibt, werden sie nicht von der Zeichenklasse dieser mittleren Gruppe angegeben. Sie könnten diesen mittleren ersetzen:

und sehen, ob das stimmt. Wenn dies der Fall ist, müssen Sie möglicherweise die Charakterklasse Ihrer mittleren Gruppe weiter verbessern.

Wenn es Ihnen egal ist, wie viele Übereinstimmungen in der mittleren Gruppe auftreten, erfassen Sie nur die Erfassung, verwenden Sie eine nicht erfassende Gruppe, um jede Untergruppe zu erfassen, und eine Gruppe, um die gesamte Gruppe von Zwischengruppen zu erfassen:

["']    # a double quote or quote 
)      # requried 
(     # a group that captures... 
    (?:    # zero or more groups of space chars, letters, 
     [\s\w:;'"=] # numbers, colon, quote, dobule quote, and equals 
    )*    # zero or more times as much as it can 
)      # UNTIL... 
(     # a group that captures... 
    (?:height|width) # height or width (non-capturing) 

Jetzt werden Sie eine feste Anzahl von Aufnahmen haben, mit dem ersten Teil immer in der Gruppe 1, die mittlere Sachen immer in der Gruppe 2 und die letzte (wenn es sie gibt) in der Gruppe 3.

+0

tolle Analyse! – inger

+0

Wunderbare Analyse, aber mein Lesen der OP-Anforderung ist die zweite Höhe/Breite-Eigenschaft ist optional, also glaube ich nicht, dass es ziemlich ist. Vielleicht habe ich falsch verstanden? – gbulmer

+0

Mmm. Ja, das ist wahr. Es reparieren. –