Nehmen Sie diesen regulären Ausdruck : /^[^abc]/
. Dies stimmt mit jedem einzelnen Zeichen am Anfang einer Zeichenfolge überein, mit Ausnahme von a, b oder c.
Wenn Sie ein Nachher hinzufügen *
- /^[^abc]*/
- fügt der reguläre Ausdruck weiterhin jedes nachfolgende Zeichen zum Ergebnis hinzu, bis er entweder ein a
, oder b
, oder erfüllt c
.
Bei der Quellzeichenfolge stimmt "qwerty qwerty whatever abc hello"
der Ausdruck beispielsweise mit überein "qwerty qwerty wh"
.
Aber was wäre, wenn ich die passende Zeichenfolge haben wollte? "qwerty qwerty whatever "
... Mit anderen Worten, wie kann ich alles auf die genaue Reihenfolge "abc"
abstimmen (aber nicht einschließen) ?
match but not including
?"qwerty qwerty whatever "
- ohne das "abc". Mit anderen Worten, ich möchte nicht, dass die resultierende Übereinstimmung vorliegt"qwerty qwerty whatever abc"
.do string.split('abc')[0]
. Sicherlich keine offizielle Antwort auf dieses Problem, aber ich finde es einfacher als Regex.Antworten:
Sie haben nicht angegeben, welche Regex-Variante Sie verwenden, aber dies funktioniert in einer der beliebtesten Versionen, die als "vollständig" angesehen werden können.
Wie es funktioniert
Der
.+?
Teil ist die ungierige Version von.+
(einer oder mehreren von irgendetwas). Wenn wir verwenden.+
, passt der Motor im Grunde zu allem. Wenn sich dann noch etwas in der Regex befindet, wird es in Schritten zurückgehen und versuchen, dem folgenden Teil zu entsprechen. Dies ist das gierige Verhalten, das bedeutet, so viel wie möglich zu befriedigen .Wenn Sie verwenden
.+?
, anstatt alle auf einmal abzugleichen und für andere Bedingungen (falls vorhanden) zurückzukehren, stimmt die Engine schrittweise mit den nächsten Zeichen überein, bis der nachfolgende Teil der Regex übereinstimmt (erneut, falls vorhanden). Dies ist das Ungierige , was bedeutet, dass es möglichst wenig zu befriedigen gibt .Danach haben wir eine Behauptung mit einer Breite von Null und sehen uns um . Diese gruppierte Konstruktion entspricht dem Inhalt, zählt jedoch nicht als übereinstimmende Zeichen ( Breite Null ). Es wird nur zurückgegeben, wenn es sich um eine Übereinstimmung handelt oder nicht ( Behauptung ).
(?=
{contents}
)
Mit anderen Worten
/.+?(?=abc)/
bedeutet der reguläre Ausdruck :quelle
.+?
und.*
?+
bedeutet 1 oder mehr, wobei*
0 oder mehr bedeutet. Das Einschließen / Ausschließen des?
Willens macht es gierig oder nicht gierig.^(?:(?!abc)(?!def).)*
Sie Kette Muster ausschließen Sie nicht wollen , und es wird immer noch greift alles nach Bedarf auch wenn das Muster nicht existiertWenn Sie alles bis "abc" erfassen möchten:
Erläuterung:
( )
erfaßt den Ausdruck in den Klammern für den Zugriff mit$1
,$2
etc.^
Spielanfang der Linie.*
stimme mit nichts überein,?
nicht gierig (stimme mit der erforderlichen Mindestanzahl von Zeichen überein) - [1][1] Der Grund, warum dies erforderlich ist, ist der folgende in der folgenden Zeichenfolge:
Standardmäßig sind reguläre Ausdrücke gierig , was bedeutet, dass sie so gut wie möglich übereinstimmen. Daher
/^.*abc/
würde "was auch immer etwas abc etwas" entsprechen. Durch Hinzufügen des nicht gierigen Quantifizierers?
stimmt der Regex nur mit "was auch immer etwas" überein.quelle
sed
scheint weder nicht gieriges Matching noch Look-around ((?=...)
) zu unterstützen. Was kann ich sonst noch tun? Beispielbefehl:echo "ONE: two,three, FOUR FIVE, six,seven" | sed -n -r "s/^ONE: (.+?), .*/\1/p"
kehrt zurücktwo,three, FOUR FIVE
, aber ich erwartetwo,three
...two
, nichttwo,three
.Wie @Jared Ng und @Issun betonten, wird der Schlüssel zum Lösen dieser Art von RegEx wie "alles mit einem bestimmten Wort oder Teilstring abgleichen" oder "alles nach einem bestimmten Wort oder Teilstring abgleichen" als "Lookaround" -Anweisungen mit null Länge bezeichnet . Lesen Sie hier mehr darüber.
In Ihrem speziellen Fall kann dies durch einen positiven Blick in die Zukunft gelöst werden:
.+?(?=abc)
Ein Bild sagt mehr als tausend Worte. Siehe die detaillierte Erklärung im Screenshot.
quelle
.+?(?=abc)
Copy-Pastable Regex ist mehr wert.Was Sie brauchen, ist sich um die Behauptung zu kümmern
.+? (?=abc)
.Siehe: Lookahead und Lookbehind Zero-Length Assertions
Seien Sie sich bewusst, dass dies
[abc]
nicht dasselbe ist wieabc
. In Klammern steht keine Zeichenfolge - jedes Zeichen ist nur eine der Möglichkeiten. Außerhalb der Klammern wird es zur Zeichenfolge.quelle
Für Regex in Java und ich glaube auch an die meisten Regex-Engines, wenn Sie den letzten Teil einschließen möchten, funktioniert dies:
Zum Beispiel in dieser Zeile:
Wählen Sie alle Zeichen bis "abc" aus und schließen Sie auch abc ein
Mit unserer Regex wird das Ergebnis sein:
I have this very nice senabc
Testen Sie dies: https://regex101.com/r/mX51ru/1
quelle
Ich endete mit dieser Frage zum Stapelüberlauf, nachdem ich nach Hilfe gesucht hatte, um mein Problem zu lösen, fand aber keine Lösung dafür :(
Also musste ich improvisieren ... nach einiger Zeit gelang es mir, den regulären Ausdruck zu erreichen, den ich brauchte:
Wie Sie sehen können, benötigte ich bis zu einem Ordner vor dem Ordner "grp-bps", ohne den letzten Bindestrich einzuschließen. Und es war erforderlich, mindestens einen Ordner nach dem Ordner "grp-bps" zu haben.
Bearbeiten
Textversion zum Kopieren und Einfügen (ändern Sie 'grp-bps' für Ihren Text):
quelle
Dies macht bei Regex Sinn.
Hier können wir das genaue Wort global erhalten, das in die doppelten Anführungszeichen gehört. Zum Beispiel, wenn unser Suchtext lautet:
Dies ist das Beispiel für Wörter in doppelten Anführungszeichen
dann werden wir aus diesem Satz "doppelt zitiert".
quelle
"
, was mir für die Frage irrelevant erscheint.Auf Python:
.+?(?=abc)
funktioniert für den einzeiligen Fall.[^]+?(?=abc)
funktioniert nicht, da Python [^] nicht als gültigen regulären Ausdruck erkennt. Damit der mehrzeilige Abgleich funktioniert, müssen Sie die Option re.DOTALL verwenden, zum Beispiel:quelle
Ich glaube, Sie brauchen Unterausdrücke. Wenn ich mich recht erinnere, können Sie die normalen
()
Klammern für Unterausdrücke verwenden.Dieser Teil stammt aus dem grep-Handbuch:
Tun Sie so etwas wie
^[^(abc)]
sollte den Trick tun.quelle
Das
$
markiert das Ende eines Strings, also sollte so etwas funktionieren:[[^abc]*]$
Wo Sie nach etwas suchen, das in keiner Iteration von ENDETabc
, aber es müsste am Ende seinAuch wenn Sie eine Skriptsprache mit Regex (wie PHP oder JS) verwenden, verfügen diese über eine Suchfunktion, die stoppt, wenn sie zum ersten Mal auf ein Muster stößt (und Sie können Start von links oder Start von rechts oder mit PHP angeben). Sie können implodieren, um die Zeichenfolge zu spiegeln.
quelle
Versuche dies
Abfrage:
Ausgabe :
quelle