Ich habe sehr ähnliche Beiträge gefunden, aber ich kann meinen regulären Ausdruck hier nicht richtig verstehen.
Ich versuche, einen regulären Ausdruck zu schreiben, der eine Zeichenfolge zurückgibt, die zwischen zwei anderen Zeichenfolgen liegt. Zum Beispiel: Ich möchte den String erhalten, der sich zwischen den Strings "cow" und "milk" befindet.
Meine Kuh gibt immer Milch
würde zurückkehren
"gibt immer"
Hier ist der Ausdruck, den ich bisher zusammengesetzt habe:
(?=cow).*(?=milk)
Dies gibt jedoch die Zeichenfolge "Kuh gibt immer" zurück.
Ein Lookahead (das (?=
part) verbraucht keine Eingabe. Es ist eine Behauptung mit der Breite Null (wie auch Grenzüberprüfungen und Lookbehinds).
Sie möchten hier eine reguläre Übereinstimmung, um den Teil cow
zu verbrauchen. Um den Teil dazwischen zu erfassen, verwenden Sie eine Erfassungsgruppe (fügen Sie einfach den Teil des Musters, den Sie erfassen möchten, in Klammern ein):
cow(.*)milk
Es werden überhaupt keine Lookaheads benötigt.
Regulärer Ausdruck, um eine Zeichenfolge zwischen zwei Zeichenfolgen in JavaScript abzurufen
Die umfassendste Lösung, die in den allermeisten Fällen funktioniert, ist die Verwendung einer Erfassungsgruppe mit einem Lazy Dot Matching Muster . Ein Punkt .
In JavaScript-Regex stimmt jedoch nicht mit Zeilenumbrüchen überein. In 100% der Fälle ist also ein [^]
Oder [\s\S]
/[\d\D]
/[\w\W]
Konstrukte.
In JavaScript-Umgebungen, die ECMAScript 2018 unterstützen, ermöglicht der Modifikator s
, dass .
Mit allen Zeichen einschließlich Zeilenumbruchzeichen übereinstimmt, und die Regex-Engine unterstützt Lookbehinds variabler Länge. Sie können also einen regulären Ausdruck verwenden
var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional
In beiden Fällen wird die aktuelle Position mit 1/0 oder mehr Leerzeichen nach cow
auf cow
überprüft, und dann werden mindestens 0 Zeichen abgeglichen und verbraucht (= zu den Zeichen hinzugefügt) match value), und dann wird milk
überprüft (mit 1/0 oder mehr Leerzeichen vor dieser Teilzeichenfolge).
Dieses und alle anderen unten aufgeführten Szenarien werden von allen JavaScript-Umgebungen unterstützt. Siehe Verwendungsbeispiele am Ende der Antwort.
cow (.*?) milk
cow
wird zuerst gefunden, dann ein Leerzeichen, dann werden alle 0+ Zeichen außer Zeilenumbruchzeichen, so wenig wie möglich, wie *?
ein verzögerter Quantifizierer ist, in Gruppe 1 und dann ein Leerzeichen erfasst mit milk
muss folgen (und diese werden abgeglichen und verbraucht auch).
cow ([\s\S]*?) milk
Hier werden zuerst cow
und ein Leerzeichen abgeglichen, dann werden mindestens 0 Zeichen abgeglichen und in Gruppe 1 erfasst, und dann wird ein Leerzeichen mit milk
abgeglichen.
Wenn Sie einen String wie >>>15 text>>>67 text2>>>
Haben und 2 Übereinstimmungen zwischen >>>
+ number
+ whitespace
und >>>
Erhalten müssen, Sie können />>>\d+\s(.*?)>>>/g
nicht verwenden, da dies nur eine Übereinstimmung findet, da >>>
vor 67
steht bereits verbraucht beim Finden der ersten Übereinstimmung. Sie können einen positiven Lookahead verwenden, um die Textpräsenz zu überprüfen, ohne sie tatsächlich zu "verschlingen" (d. H an das Spiel anhängen):
/>>>\d+\s(.*?)(?=>>>)/g
Sehen Sie sich die Online-Regex-Demo an, die text1
Und text2
Als Inhalt von Gruppe 1 ergibt.
Siehe auch Wie man alle möglichen überlappenden Übereinstimmungen für einen String erhält .
Lazy-Dot-Matching-Muster (.*?
) In Regex-Mustern können die Skriptausführung verlangsamen, wenn sehr lange Eingaben gemacht werden. In vielen Fällen hilft Unroll-the-Loop-Technik in größerem Maße. Beim Versuch, alle zwischen cow
und milk
aus "Their\ncow\ngives\nmore\nmilk"
Zu holen, müssen wir nur alle Zeilen abgleichen, die nicht mit milk
beginnen. Anstelle von cow\n([\s\S]*?)\nmilk
können wir verwenden:
/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm
Siehe die Regex-Demo (wenn es \r\n
Geben kann, benutze /cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
). Bei dieser kleinen Testzeichenfolge ist der Leistungszuwachs vernachlässigbar, aber bei sehr großem Text werden Sie den Unterschied bemerken (insbesondere, wenn die Zeilen lang sind und die Zeilenumbrüche nicht sehr zahlreich sind).
Beispiel für die Verwendung von Regex in JavaScript:
//Single/First match expected: use no global modifier and access match[1] console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]); // Multiple matches: get multiple matches with a global modifier and // trim the results if length of leading/trailing delimiters is known var s = "My cow always gives milk, thier cow also gives milk"; console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);})); //or use RegExp#exec inside a loop to collect all the Group 1 contents var result = [], m, rx = /cow (.*?) milk/g; while ((m=rx.exec(s)) !== null) { result.Push(m[1]); } console.log(result);
Hier ist ein regulärer Ausdruck, der festhält, was sich zwischen Kuh und Milch befindet (ohne führende/nachfolgende Leerstelle):
srctext = "My cow always gives milk.";
var re = /(.*cow\s+)(.*)(\s+milk.*)/;
var newtext = srctext.replace(re, "$2");
Ein Beispiel: http://jsfiddle.net/entropo/tkP74/
.*
Erfassen.*
- Fehler machenDer Lookahead ist wirklich nicht nötig.
> /cow(.*?)milk/i.exec('My cow always gives milk');
["cow always gives milk", " always gives "]
Mit der folgenden Lösung von Martinho Fernandes konnte ich das bekommen, was ich brauchte. Der Code lautet:
var test = "My cow always gives milk";
var testRE = test.match("cow(.*)milk");
alert(testRE[1]);
Sie werden feststellen, dass ich die Variable testRE als Array alarmiere. Dies liegt daran, dass testRE aus irgendeinem Grund als Array zurückgegeben wird. Die Ausgabe von:
My cow always gives milk
Änderungen in:
always gives
Verwenden Sie einfach den folgenden regulären Ausdruck:
(?<=My cow\s).*?(?=\smilk)
Die Methode match () durchsucht einen String nach einer Übereinstimmung und gibt ein Array-Objekt zurück.
// Original string
var str = "My cow always gives milk";
// Using index [0] would return<br/>
// "**cow always gives milk**"
str.match(/cow(.*)milk/)**[0]**
// Using index **[1]** would return
// "**always gives**"
str.match(/cow(.*)milk/)[1]