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 aufgenommen wird, obwohl er sich über Zeilenumbrüche erstreckt. Ich dachte, die 'm'-Flagge macht es. Nicht.
Hier vor dem Posten die Antwort gefunden . Da ich dachte, ich kenne JavaScript (drei Bücher lesen, Arbeitsstunden) und es bei SO keine Lösung gab, werde ich es trotzdem wagen, etwas zu posten. wirf hier Steine
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?
Bearbeiten: Dies ist ein Duplikat, aber da es schwieriger zu finden ist als meins, entferne ich es nicht.
Es wird [^]
als "mehrzeiliger Punkt" vorgeschlagen. Was ich immer noch nicht verstehe ist, warum [.\n]
es nicht funktioniert. Ich denke, dies ist einer der traurigen Teile von JavaScript.
javascript
regex
Akauppi
quelle
quelle
Antworten:
[.\n]
funktioniert nicht, weil.
es keine besondere Bedeutung hat[]
, es bedeutet nur ein Literal.
.(.|\n)
wäre eine Möglichkeit, "ein beliebiges Zeichen, einschließlich einer neuen Zeile" anzugeben. Wenn Sie alle Zeilenumbrüche abgleichen möchten, müssen Sie auch Zeilenenden\r
für Windows und klassische Mac OS-Zeilen hinzufügen :(.|[\r\n])
.Das stellt sich als etwas umständlich und langsam heraus (siehe KrisWebDevs Antwort für Details ). Ein besserer Ansatz wäre es daher, alle Leerzeichen und alle Nicht-Leerzeichen mit zu vergleichen
[\s\S]
, die zu allem passen und schneller und schneller sind einfacher.Im Allgemeinen sollten Sie nicht versuchen, einen regulären Ausdruck zu verwenden, der mit den tatsächlichen HTML-Tags übereinstimmt. Weitere Informationen zum Warum finden Sie beispielsweise in diesen Fragen .
Versuchen Sie stattdessen, das DOM tatsächlich nach dem gewünschten Tag zu durchsuchen (die Verwendung von jQuery erleichtert dies, aber Sie können dies immer
document.getElementsByTagName("pre")
mit dem Standard-DOM tun ), und durchsuchen Sie dann den Textinhalt dieser Ergebnisse mit einem regulären Ausdruck, wenn Sie mit dem Inhalt übereinstimmen müssen .quelle
[\r\n]
angewendet auf eine Sequenz \ r \ n, würde zuerst \ r und dann \ n übereinstimmen. Wenn Sie die gesamte Sequenz auf einmal abgleichen möchten, unabhängig davon, ob diese Sequenz \ r \ n oder nur \ n ist, verwenden Sie das Muster.|\r?\n
[\s\S]+
..
innen[]
ist anders als andere Regex - Frameworks, insbesondere die fortschrittlichste in .NET. Leute, bitte geht nicht davon aus, dass Regexe plattformübergreifend sind, das sind sie häufig nicht !!NICHT
(.|[\r\n])
anstelle von.
mehrzeiligem Matching verwenden.Verwenden Sie
[\s\S]
anstelle von.
für mehrzeiligen AbgleichVermeiden Sie auch greediness wo nicht benötigt durch die Verwendung
*?
oder+?
quantifier statt*
oder+
. Dies kann enorme Auswirkungen auf die Leistung haben.Siehe den von mir erstellten Benchmark: http://jsperf.com/javascript-multiline-regexp-workarounds
NB: Sie können auch verwenden,
[^]
aber es ist im folgenden Kommentar veraltet.quelle
[^]
trotzdem nicht zu verwenden. Einerseits ist JavaScript die einzige mir bekannte Variante, die diese Redewendung unterstützt, und selbst dort wird sie bei weitem nicht so oft verwendet wie[\s\S]
. Auf der anderen Seite können Sie mit den meisten anderen Geschmacksrichtungen dem entkommen,]
indem Sie es zuerst auflisten. Mit anderen Worten, in JavaScript[^][^]
paßt alle zwei Charaktere, aber in .NET Entsprechung für jeden ein anderes Zeichen als]
,[
oder^
.\S
das zu\r
oder\n
gegen einen anderen Charakter passt?[\s\S]
anderen den Vorzug zu geben , wie[\d\D]
oder[\w\W]
?/<p>Can[^]*?<\/p>/
stimmt nicht mit dem gleichen Inhalt überein wie/<p>Can[^]*<\/p>/
. Die gierige Variante sollte so geändert werden, dass/<p>(?:[^<]|<(?!\/p>))*<\/p>/
sie dem gleichen Inhalt entspricht.Sie geben Ihre Umgebung und Version von Javascript (ECMAscript) nicht an, und mir ist klar, dass dieser Beitrag aus dem Jahr 2009 stammt. Der Vollständigkeit halber können wir mit der Veröffentlichung von ECMA2018 jetzt das
s
Flag verwenden, um.
die Übereinstimmung mit '\ n' zu bewirken , siehe https : //stackoverflow.com/a/36006948/141801So:
Dies ist eine neue Erweiterung, die in vielen aktuellen Umgebungen nicht funktioniert. Beispielsweise scheint Node v8.7.0 sie nicht zu erkennen, funktioniert jedoch in Chromium und ich verwende sie in einem Typescript-Test, den ich schreibe, und vermutlich auch wird im Laufe der Zeit mehr Mainstream werden.
quelle
[.\n]
funktioniert nicht, weil dot in[]
(per Regex-Definition; nicht nur Javascript) das Punktzeichen bedeutet. Sie können stattdessen(.|\n)
(oder(.|[\n\r])
) verwenden.quelle
[\s\S]
ist die gebräuchlichste JavaScript-Redewendung, um alles abzugleichen, einschließlich Zeilenumbrüche. Es ist augenschonender und viel effizienter als ein alternationsbasierter Ansatz wie(.|\n)
. (Es bedeutet wörtlich "jedes Zeichen, das Leerzeichen ist, oder jedes Zeichen, das kein Leerzeichen ist.).
und\n
, und warum[.\n]
funktioniert nicht. Wie in der Frage erwähnt,[^]
ist das auch ein netter Ansatz.Ich habe es getestet (Chrome) und es funktioniert für mich (beide
[^]
und[^\0]
), indem ich den Punkt (.
) entweder[^\0]
oder[^]
geändert habe, weil der Punkt nicht mit dem Zeilenumbruch übereinstimmt (siehe hier:http://www.regular-expressions.info/dot.html ).quelle
[^\0]
ist, dass es nicht mit Nullzeichen übereinstimmt, obwohl Nullzeichen in Javascript-Zeichenfolgen zulässig sind (siehe diese Antwort ).Zusätzlich zu den oben genannten Beispielen ist es eine Alternative.
Wo
\w
ist für Wörter und\s
ist für Leerzeichenquelle