JavaScriptの正規表現を複数の行で使用する方法は?


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

改行文字にまたがっていても、PREブロックを取得したいのですが。私は「m」フラグがそれを行うと思った。ではない。

投稿する前にここで答えを見つけました。私はJavaScript(3冊の本を読み、何時間も作業する)を知っていて、SOに既存のソリューションがなかったと思ったので、とにかく投稿するつもりです。ここに石を投げる

したがって、解決策は次のとおりです。

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

誰かがより不可解な方法を持っていますか?

編集:これは複製ですが、私のものより見つけるのが難しいので、削除しません。

[^]「マルチラインドット」として提案します。私がまだ理解していないのは、なぜ[.\n]機能しないのかです。これはJavaScriptの悲しい部分の1つだと思います。


29
より不可解な正規表現?本来、不可能です。
ルーベンスファリアス

ところで、「Htmlの解析:クトゥルフの方法」codinghorror.com/blog/archives/001311.html
ルーベンスファリアス

1
リンクは前のコメントから変更されました:blog.codinghorror.com/parsing-html-the-cthulhu-way(5歳未満)
dab

回答:


248

[.\n].内部には特別な意味がないため、機能しません。[]リテラルを意味するだけ.です。(.|\n)「改行を含む任意の文字」を指定する方法です。すべての改行を一致させる場合\rは、Windowsと従来のMac OSスタイルの行末を含めるためにも追加する必要があります(.|[\r\n])

これはやや面倒であるだけでなく、速度も遅いことが判明しているため(詳細についてはKrisWebDevの回答を参照)、すべての空白文字とすべての非空白文字を一致させることをお勧めし[\s\S]ます。より簡単です。

一般に、実際のHTMLタグと一致させるために正規表現を使用しないでください。理由の詳細については、たとえば、これらの 質問を参照してください。

代わりに、実際にDOMで必要なタグを検索してみてください(jQueryを使用するとこれが簡単になりますがdocument.getElementsByTagName("pre")、標準のDOMでいつでも実行できます)。次に、コンテンツと照合する必要がある場合は、正規表現を使用して結果のテキストコンテンツを検索します。 。


私がやっていることは、JavaScriptを使用して.wiki-> HTML変換をその場で行うことです。そのため、まだDOMを利用できません。Wikiファイルは主に独自の構文ですが、必要に応じてHTMLタグを使用することを許可しています。私がこれをDOMで扱っていたなら、あなたのアドバイスはとても有効です。ありがとう。:)
akauppi

けっこうだ。HTMLで混合されたWiki構文には、あらゆる種類の楽しいコーナーケースが存在する可能性がありますが、これがHTMLで正規表現を使用する正当な理由だと思います。
ブライアンキャンベル

2
[\r\n]シーケンスに適用されます\ r \ n、最初に\ rに一致し、次に\ nに一致します。シーケンス全体を一度に照合する場合は、そのシーケンスが\ r \ nまたは単に\ nであるかどうかに関係なく、パターンを使用します.|\r?\n
Eirik Birkeland

1
複数行の文字列全体を照合するには、貪欲を試してください[\s\S]+
Boaz

.内部の意味を無視するJS正規表現構文が他の正規表現フレームワーク、特に.NETの高度なフレームワーク[]とは異なることを後世に付け加えたいだけです。人々は、正規表現がクロスプラットフォームであると仮定しないでください、彼らはしばしばそうではありません !!
TA氏、

330

複数行マッチングの(.|[\r\n])代わりに使用しないでください.

複数行マッチングの[\s\S]代わりに使用してください.

また、*?orの+?代わりに*or 数量詞を使用して、必要のない貪欲さを回避し+ます。これはパフォーマンスに大きな影響を与える可能性があります。

私が作成したベンチマークを参照してください: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

注意:使用することもできます[^]が、以下のコメントでは非推奨です。


22
良い点ですが、[^]とにかく使用しないことをお勧めします。一方では、JavaScriptがそのイディオムをサポートする唯一のフレーバーであり、JavaScriptはほど頻繁には使用されていません[\s\S]。一方、他のほとんどのフレーバーでは、]最初にリストすることでエスケープできます。言い換えれば、JavaScriptで[^][^]任意の2つの文字と一致しますが、.NETにそれはどんなマッチする1の以外の文字を][または^
アランムーア

1
それ\Sが他のキャラクターと一致する\rか、または\n他のキャラクターと比較してどうしてわかりますか?
ギリ

3
参照してくださいこの質問を \ S \ Sの詳細については。これは、すべての空白文字+すべての非空白文字=すべての文字に一致するハックです。正規表現の特殊文字のドキュメントについては、MDNも参照してください。
KrisWebDev 2013

4
または?[\s\S]など、他のユーザーよりも優先する理由 [\d\D][\w\W]
Phrogz 2017年

1
貪欲なオペレーターのテストは不正であることを簡単に指摘しておきます。/<p>Can[^]*?<\/p>/と同じコンテンツに一致しません/<p>Can[^]*<\/p>/。貪欲なバリアントは/<p>(?:[^<]|<(?!\/p>))*<\/p>/、同じコンテンツに一致するように変更する必要があります。
3limin4t0r

19

あなたはあなたの環境とJavascript(ECMAscript)のバージョンを指定していません、そして私はこの投稿が2009年からだったことに気づきました、しかし完全を期すために、ECMA2018のリリースでsフラグを使用して.'\ n'と一致させることができるようになりました、httpsを参照してください://stackoverflow.com/a/36006948/141801

したがって:

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

これは最近の追加であり、現在の多くの環境では機能しません。たとえば、ノードv8.7.0はそれを認識していないようですが、Chromiumで機能し、Typescriptテストで使用しています。時間が経つにつれてより主流になります。


1
これはChrome(v67)でうまく機能しますが、IE11とIEdge(v42)の正規表現を完全に無効にします(行ごとの機能も停止します)
freedomn-m

おかげで@ freedomn-m .. IEが非常に新しい機能をサポートしていないことは、ほぼ完全に驚くことではありません:)しかし、はい、それを使用しようとする人が「デバッグ」しようとしても機能しない理由を救うために機能しない場所について言及する価値があります予想通り。
Neek、2013

11

[.\n]ドットイン[](正規表現の定義による。JavaScriptのみではない)はドット文字を意味するため、機能しません。代わりに(.|\n)(または(.|[\n\r]))を使用できます。


24
[\s\S]改行を含むすべてに一致させるための最も一般的なJavaScriptイディオムです。これは、目に優しく、のような代替ベースのアプローチよりもはるかに効率的です(.|\n)。(これは、文字通り「任意の文字を意味している空白または任意の文字ではない空白を。)
アラン・ムーア

2
あなたは正しいですが、問題はとについてで.あり\n、なぜ[.\n]機能しないのですか?質問で述べたように、これ[^]も素晴らしいアプローチです。
Y.ショーハム、2010年

6

私は(クローム)を、それをテストしているし、それは私のために働いて(両方[^][^\0](ドットを変更することで、).のいずれかにより)、[^\0]または[^]ドットが改行と一致しないため、(ここを参照してください: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


1
の問題[^\0]は、Javascript文字列でnull文字が許可されていても、null文字と一致しないことです(この回答を参照)。
ドナルドダック

0

上記の例に加えて、これは代替手段です。

^[\\w\\s]*$

どこ\wが単語で、\sが空白

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.