Frage

Wie würde man einen regulären Ausdruck schreiben, die einem Muster entspricht, die Anführungszeichen enthalten kann, aber wenn es der Fall ist, müssen Anführungszeichen am Anfang und Ende passend?

"?(pattern)"?

werde nicht funktionieren, weil es Muster ermöglichen, die mit einem Zitat beginnen, aber nicht mit einem Ende.

"(pattern)"|(pattern)

funktioniert, aber ist repetitiv. Gibt es einen besseren Weg, dies zu tun, ohne das Muster zu wiederholen?

War es hilfreich?

Lösung

Sie können eine Lösung erhalten, ohne Wiederholung durch die Nutzung von Rückreferenzierungen und conditionals :

/^(")?(pattern)(?(1)\1|)$/

Ergebnisse:

  • Muster
  • "Muster"

Keine Übereinstimmung:

  • "Muster
  • Muster "

Dieses Muster etwas komplex, aber. Es sucht zuerst für ein optionales Angebot, und legt es in Rückreferenzierung 1, wenn eine gefunden wird. Dann sucht es nach Ihrem Muster. Dann verwendet sie bedingte Syntax zu sagen „wenn Rückreferenzierung 1 wieder gefunden wird, es passen, sonst nichts passen“. Das ganze Muster ist verankerten (was bedeutet, dass sie von selbst auf einer Zeile angezeigt werden muss) so dass unerreichte Quotes werden nicht erfasst werden (sonst die pattern in pattern" würde übereinstimmen).

Beachten Sie, dass die Unterstützung für conditionals variiert je nach Motor und ausführlicher, aber sich wiederholende Ausdrücke mehr werden umfassend unterstützt (und wahrscheinlich leichter zu verstehen).


Update: Eine einfachere Version dieser regex wäre /^(")?(pattern)\1$/, die nicht eine bedingte benötigt. Als ich dies zunächst die Prüfung wurde der Tester war ich mit mir ein falsch negativen, was mich zu Rabatt führt sie (oops!).

Ich werde die Lösung mit der bedingten up für die Nachwelt und Zinsen verlassen, aber das ist eine einfachere Version, die in einer größeren Vielfalt von Motoren eher Arbeit (Rückreferenzierungen sind das einzige Merkmal hier verwendet werden, die nicht unterstützt sein könnte) .

Andere Tipps

Je nach Sprache, die Sie verwenden, sollten Sie in der Lage sein Rückreferenzierungen zu verwenden. So etwas wie dies, sagen:

(["'])(pattern)\1|^(pattern)$

Auf diese Weise Sie erfordern, dass entweder keine Anführungszeichen sind, oder dass die SAME Angebot an beiden Enden verwendet wird.

Dies sollte mit rekursiven regex arbeiten (was mehr richtig zu machen braucht). In der Zwischenzeit: in Perl können Sie bauen ein selbst-modifizierenden regex . Ich werde das als akademisches Beispiel lassen; -)

my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern'  );

foreach (@stuff) {
   print "$_ OK\n" if /^
                        (")?
                        \w+
                        (??{defined $1 ? '"' : ''})
                       $
                      /x
}

Ergebnis:

"pattern" OK
pattern OK
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top