it-swarm.com.de

Verwendung von JavaScript-Regex über mehrere Zeilen

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr);     // null

Ich möchte, dass der PRE-Block abgeholt wird, obwohl er Zeilenumbrüche umfasst. Ich dachte, die "m" -Fahne macht es. Nicht.

Die Antwort hier vor dem Posten gefunden. Seitdem dachte ich, ich kenne JavaScript (habe drei Bücher gelesen und gearbeitet) und es gab keine Lösung bei SO, ich wage es trotzdem zu posten. Steine ​​werfen

Die Lösung lautet also:

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr);     // <pre>...</pre> :)

Hat jemand einen weniger kryptischen Weg?

Edit: this ist ein Duplikat, aber da es schwerer zu finden ist als meiner, entferne ich es nicht.

Es schlägt [^] als "mehrzeiligen Punkt" vor. Was ich immer noch nicht verstehe ist, warum [.\n] nicht funktioniert. Ratet mal, das ist einer der traurigen Teile von JavaScript.

223
akauppi

[.\n] funktioniert nicht, da . innerhalb von [] keine besondere Bedeutung hat, es bedeutet nur ein Literal .. (.|\n) wäre eine Möglichkeit, "jedes Zeichen, einschließlich einer Zeile" anzugeben. Wenn Sie alle Zeilenumbrüche abgleichen möchten, müssen Sie auch \r hinzufügen, um die Zeilenenden von Windows und klassischen Mac OS-Stilen aufzunehmen: (.|[\r\n]).

Das stellt sich als etwas umständlich und langsam heraus (siehe Antwort von KrisWebDev für Details ). Ein besserer Ansatz wäre, alle Whitespace-Zeichen und alle Nicht-Whitespace-Zeichen mit [\s\S] abzugleichen und ist schneller und einfacher.

Im Allgemeinen sollten Sie nicht versuchen, mit einem regulären Ausdruck die tatsächlichen HTML-Tags abzugleichen. Siehe dieseFragen für mehr Informationen darüber, warum.

Versuchen Sie stattdessen, das DOM nach dem Tag zu durchsuchen, den Sie benötigen (mit jQuery ist dies einfacher, aber Sie können document.getElementsByTagName("pre") immer mit dem Standard-DOM tun), und dann den Textinhalt dieser Ergebnisse mit einem regulären Ausdruck durchsuchen, wenn Sie mit dem übereinstimmen müssen Inhalt.

197
Brian Campbell

Verwenden Sie NICHT (.|[\r\n]) anstelle von . für den Abgleich mit mehreren Zeilen.

Verwenden Sie [\s\S] anstelle von . für den Abgleich mit mehreren Zeilen

Vermeiden Sie auch die Habgierigkeit, wenn dies nicht erforderlich ist, indem Sie *? oder +? quantifier statt * oder + verwenden. Dies kann große Auswirkungen auf die Leistung haben.

Siehe den Benchmark, den ich erstellt habe: http://jsperf.com/javascript-multiline-regexp-workarounds

Using [^]: fastest
Using [\s\S]: 0.83% slower
Using (.|\r|\n): 96% slower
Using (.|[\r\n]): 96% slower

NB: Sie können auch [^] verwenden, es ist jedoch im folgenden Kommentar veraltet.

292
KrisWebDev

[.\n] funktioniert nicht, da ein Punkt in [] (durch Regex-Definition; nicht nur Javascript) das Punktzeichen bedeutet. Sie können stattdessen (.|\n) (oder (.|[\n\r])) verwenden.

12
Y. Shoham

Sie geben nicht Ihre Umgebung und Version von Javascript (ECMAscript) an. Ich weiß, dass dieser Beitrag aus dem Jahr 2009 stammt, aber der Vollständigkeit halber können wir mit der Veröffentlichung von ECMA2018 jetzt das Flag s verwenden, um zu bewirken, dass . '\ n' entspricht. siehe https://stackoverflow.com/a/36006948/141801

Somit:

let s = 'I am a string\nover several\nlines.';
console.log('String: "' + s + '".');

let r = /string.*several.*lines/s; // Note 's' modifier
console.log('Match? ' + r.test(s); // 'test' returns true

Dies ist eine kürzlich hinzugefügte Erweiterung, die in vielen aktuellen Umgebungen nicht funktioniert. Zum Beispiel scheint Node v8.7.0 dies nicht zu erkennen, aber es funktioniert in Chromium, und ich verwende es in einem TypeScript-Test, den ich schreibe und vermutlich auch wird mit der Zeit mehr Mainstream.

10
Neek

Ich habe es getestet (Chrome) und es funktioniert für mich (sowohl [^] als auch [^\0]), indem ich den Punkt (.) entweder durch [^\0] oder [^] ändere, da der Punkt nicht mit dem Zeilenumbruch übereinstimmt (Siehe hier:  http://www.regular-expressions.info/dot.html).

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[^\0]*?<\/pre>/gm );
alert(arr);     //Working

6
KhunRan

Neben den oben genannten Beispielen handelt es sich um eine Alternative.

^[\\w\\s]*$

Wo \w steht für Wörter und \s steht für Leerzeichen

0
itz-azhar