2016-12-04 1 views
1

Was allgemein (dh keine für das Muster als Ganzes spezifischen Literale) Der Unterausdruck PCRE zwischen zwei Unterausdrücken, die jeweils aus Literalzeichen bestehen, bewirkt, dass das Muster der kleinsten Zahl entspricht von Charakteren?Regex mit der kleinsten Anzahl von Zeichen

Beachten Sie, dass diese Frage nicht erfüllt ist:

  • Eine bestehende Antwort auf this related question.

  • Alle vorhandenen Antworten zu anderen verwandten Fragen, die ich auf dieser Website gefunden habe, einschließlich aller Vorschläge von Fragen, die möglicherweise bereits Ihre Antwort haben.

  • .*? (faul). Dies (wie angegeben here) stimmt nicht unbedingt mit der kleinsten Anzahl von Zeichen überein.

  • Dabei ist x ein Literalzeichen, das von einer anderen Stelle im Muster kopiert wurde. Die Anforderung ist für einen Ausdruck, der allgemein ist, d. H. Keine Literale enthält, die für das Muster als Ganzes spezifisch sind. Um solche falschen Antworten zu vermeiden, liefert diese Frage bewusst keine Beispiele für fehlgeschlagene Muster.

+0

Nun, ein gutes Beispiel wäre in einem Ihrer Links: 'abcabk', wobei' a. +? K' die ganze Zeichenfolge und nicht nur die letzten 3 Zeichen enthält. (Wo ist eine Lösung in der Tat das Doppelzeichen in eine Not-Set kopieren - die Sie vermeiden möchten.) – usr2564301

+0

Was willst du eigentlich tun? – Robert

+0

Diese Website ist für spezifische Fragen zu aktuellen Problemen vorgesehen. Ihre Frage ist viel zu vage und weit gefasst. Wählen Sie, um zu schließen, bis es spezifischer wird, mit einer tatsächlichen Problembeschreibung und einer bestimmten Frage. –

Antwort

2

Diese Regex findet die kürzeste Spiel, das mit left beginnt und endet mit right und ermöglicht einen beliebigen Text dazwischen:

(left)(?:(?!(?1)).)*?(?:right) 

Diese Regex funktioniert mit PCRE und jedem anderen Geschmack, subroutine calls unterstützt. Die left und right Bits müssen nicht wörtlicher Text sein. Sie können beliebige Regex sein, solange sie nicht mit demselben Text übereinstimmen. Das einzige andere Problem, das Sie berücksichtigen müssen, ist, dass, wenn left und right Erfassungsgruppen enthalten, die Nummern dieser Gruppen im Vergleich zu left und right als eigenständige Regexe verschoben werden.

Backtracking Regex-Engines geben immer das Spiel ganz links zurück. In dem Fall, in dem sich left und right unterscheiden, können wir erzwingen, dass die kürzeste Übereinstimmung zurückgegeben wird, indem sichergestellt wird, dass die Übereinstimmung nicht mehr als einmal left enthält.

Wenn left und right identisch sind, gibt es keine reine Regex-Lösung. Sie können dann die Zeichenfolge entlang aller Übereinstimmungen von left aufteilen und dann die kürzeste Zeichenfolge im resultierenden Array finden.

+0

Das ist großartig, funktioniert aber möglicherweise nicht, wenn das linke und das rechte Teilmuster mit der gleichen Sache übereinstimmen. – Walf

+0

@jan Ah, cool. Ein negativer Lookahead, bei dem eine Subroutine verwendet wird, um das linke Literal zu referenzieren und dadurch die linke vom Körper auszuschließen. Und dann wurde die Körper-Wildcard faul gemacht, um das richtige Literal aus dem Körper auszuschließen. Obwohl es die Anforderung nicht ganz erfüllt ("zwischen zwei Unterausdrücken platziert, die jeweils aus/literal/Zeichen bestehen"), ist es sicherlich nützlich und die beste Antwort bisher! :-) Vielen Dank. – ChrisJJ

+0

@Walf Ich konnte einen solchen Fehlerfall nicht finden. Kannst du einen zitieren? – ChrisJJ

Verwandte Themen