2010-12-31 9 views
3

Ich versuche zu verhindern, dass der \ G-Anker den Anfang der Zeichenfolge entspricht. Ich möchte nur, dass es am Ende des letzten Regex-Matches übereinstimmt.Fortsetzung am Ende der vorherigen Übereinstimmung in RegEx (PCRE)

Bei dem folgenden Text:

Pig, Cow, Goat 
fruit: apple, orange, peach, pear 
vegetable: Carrot, Lettuce, Cellery 

Und dieses Muster:

(fruit:|\G)([\w]+|[\, ]) 

ich es nur Spiel Worte nach „Frucht“ will, aber ich brauche es jedes Wort einzeln zu erfassen. Wenn ich am Ende dieses Musters einfach ein + setze, würde es alle Wörter nach "fruit:" abgleichen, aber es würde nur "pear" erfassen, wenn jede Iteration von + auf das letzte stampft.

Hier ist das Problem. Dieses Muster funktioniert, außer dass es auch "Schwein, Kuh und Ziege" entspricht, weil \ G das Ende der letzten Übereinstimmung oder den Anfang der ganzen Zeichenfolge abgleicht. Wie kann ich verhindern, dass der Anfang der gesamten Zeichenfolge übereinstimmt?

Ich benutze PCRE in PHP und ich habe Rubular.com verwendet, um mir zu helfen, schnelle Tests zu machen.

Antwort

6

Für mein Auge, Sie Regex war nicht geben Sie, was Sie sagten, Sie wollten. Du hast gesagt, du wolltest jedes Wort nach "fruit:". In Anbetracht Ihres Beispiels glaube ich nicht, dass Ihr erster Versuch Ihnen das wirklich gegeben hat. Versuchen:

(?:fruit:\s*|\G,\s*)(\w+) 

Wenn Sie alle übereinstimmen, dass sollte geben Sie die Wörter ohne Leerzeichen oder Interpunktion.

Hier ein Überblick:

  • (?: - Start Gruppe
  • fruit:\s* Nicht-Erfassung - die Präambel für eine gute Partie
  • | - oder
  • \G,\s*) - die letzten Spiel Position, ein Komma und null oder mehr Leerzeichen
  • (\w+) erfassen Sie ein oder mehrere Wortzeichen

EDIT:

den Fall zu verhindern, in dem Sie ein Spiel in der ersten Zeile erhalten, wenn die erste Zeile mit einem Komma durch ein oder mehr durch Komma getrennte Worten gefolgt beginnt, fügen Sie einfach ein negativen Null-Breite Blick hinter auf dem Start Anker kurz vor den \G:

(?:fruit:\s*|(?<!^)\G,\s*)(\w+) 
+0

Wo dies mir geholfen hat, ist, dass Sie das Trennzeichen enthalten haben ',' nach dem '\ G'. Interessante Idee. Mein Problem ist, dass das Trennzeichen und das Leerzeichen optional sind. Da sie optional sind, könnte dieses Muster leicht mit dem Anfang des Dokuments "Schwein" beginnen, über das ich keine Kontrolle habe. Ich habe auch nicht erklärt, dass ich 'preg_replace' benutze und ich möchte das Wort' fruit: 'separat abgleichen, damit ich es mit der replace-Zeichenkette dorthin zurückversetzen kann. Daher habe ich '?:' Nicht in meinem Muster verwendet. – Andrew

+0

Werfen Sie Klammern um die Frucht, um sie einzufangen. In Bezug auf das Trennzeichen und den Raum, die optional sind, wie würden Sie dann die Wörter trennen? – RobertB

+0

Eine andere Sache ...Das \ G für mich, zumindest wie ich es in das obige Muster lege, scheint nicht den Anfang einer Zeile zu erfassen, es sei denn, es ist die erste Zeile, und diese erste Zeile beginnt mit einem Komma. Verwenden Sie einige Optionen, die Sie nicht erwähnt haben? "Punkt entspricht Newline"? "^ $ Übereinstimmung bei Zeilenumbrüchen"? – RobertB