正規表現の複数行にまたがる任意の文字と一致するにはどうすればよいですか?
質問
たとえば、この正規表現は
(.*)<FooBar>
一致します:
abcde<FooBar>
しかし、複数行にわたって一致させるにはどうすればよいでしょうか?
abcde
fghij<FooBar>
解決
言語によって異なりますが、正規表現パターンに追加できる修飾子が必要です。 PHPの場合:
/(.*)<FooBar>/s
末尾の s により、ドットは改行を含むすべての 文字に一致します。
他のヒント
これを試してください:
((.|\n)*)<FooBar>
基本的に、「任意の文字または改行」と表示されます。 0回以上繰り返されます。
Eclipse検索を使用している場合、「DOTALL」を有効にできます。 「。」を作成するオプション行区切り文字を含む任意の文字に一致します:&quot;(?s)&quot;を追加するだけです検索文字列の先頭。例:
(?s).*<FooBar>
問題は、。
が任意の文字にパターンマッチできるかどうかです。答えはエンジンごとに異なります。主な違いは、パターンがPOSIXまたは非POSIX正規表現ライブラリで使用されるかどうかです。
lua-patterns :正規表現とは見なされませんが、。
はPOSIXベースのエンジンと同様に、そこにある任意の文字と一致します。
matlab および octave :。
は任意の文字に一致デフォルト(デモ): str =&quot; abcde \ n fghij&lt; Foobar&gt;&quot ;;式= '(。*)&lt; Foobar&gt; *'; [tokens、matches] = regexp(str、expression、 'tokens'、 'match');
( tokens
には abcde \ n fghij
アイテムが含まれます)。
また、すべてのboost 正規表現文法では、ドットはデフォルトで改行に一致します。 BoostのECMAScript文法により、 regex_constants :: no_mod_m
( sourceでこれをオフにできます。 )。
oracle (POSIXベース)、 n
オプション(デモ): select regexp_substr( 'abcde' || chr(10)|| 'fghij&lt; Foobar&gt; '、'(。*)&lt; Foobar&gt; '、1、1、' n '、1)デュアルの結果として
POSIXベースのエンジン:
単なる。
はすでに改行に一致し、修飾子を使用する必要はありません。 bash (デモ)。
tcl (デモ)、 postgresql (デモ)、 r (TRE、 perl = TRUE
、 perl = TRUE
を含むベースR、または stringr / stringi パターンの場合、(?s)
を使用しますインライン修飾子)(デモ)も。
を同様に扱います。
ただし、ほとんどのPOSIXベースのツールは行ごとに入力を処理します。したがって、。
は、スコープ内にないという理由だけで改行と一致しません。これをオーバーライドする方法の例を次に示します。
- sed -複数の回避策があります。最も正確だがあまり安全ではないのは
sed 'H; 1h; $!d; x; s /\(.*\)>&lt; Foobar&gt; / \ 1 / '
(H; 1h; $!d; x;
はファイルをメモリに丸lurみします)。行全体を含める必要がある場合は、sed '/ start_pattern /、/ end_pattern / d'ファイル
(開始から削除すると一致する行が含まれて終了します)またはsed '/ start_pattern /、/ end_pattern / {{//!d;};} 'ファイル
(一致する行は除外)を検討できます。 - perl -
perl -0pe 's /(.*)< FooBar&gt; / $ 1 / gs'&lt;&lt;&lt; &quot; $ str&quot;
(-0
はファイル全体をメモリに丸lurみし、-p
は-e <で指定されたスクリプトを適用した後にファイルを印刷します/ code>)。
-000pe
を使用するとファイルが丸みされ、Perlがレコード区切り文字として連続する改行(\ n \ n
)を使用する「段落モード」がアクティブになることに注意してください。 - gnu-grep -
grep -Poz '(?si)abc \ K。*?(?=&lt; Foobar&gt;)'ファイル
。ここで、z
はファイルの丸sみを有効にし、(?s)
は。
パターン、(?i)のDOTALLモードを有効にしますcode>は大文字と小文字を区別しないモードを有効にし、
\ K
はこれまでに一致したテキストを省略し、*?
は遅延量指定子、(?=&lt; Foobar&gt;)
は、&lt; Foobar&gt;
の前の場所と一致します。 - pcregrep -
pcregrep -Mi &quot;(?si)abc \ K。*?(?=&lt; Foobar&gt;)&quot; file
(M
はここでファイルの丸lurみを有効にします)。注pcregrep
は、Mac OSのgrep
ユーザーに適したソリューションです。
非POSIXベースのエンジン:
- php -
s <を使用
修飾子 PCRE_DOTALL修飾子:preg_match( ' 〜(。*)&lt; Foobar&gt;〜s '、$ s、$ m)
(デモ ) - c#-
を使用RegexOptions.Singleline
フラグ(デモ):
-var result = Regex.Match (s、@&quot;(。*)&lt; Foobar&gt;&quot;、RegexOptions.Singleline).Groups [1] .Value;
-var result = Regex.Match(s、@ &quot;(?s)(。*)&lt; Foobar&gt;&quot;)。Groups [1] .Value;
- powershell -
(? s)
インラインオプション:$ s =&quot; abcde`nfghij&lt; FooBar&gt;&quot ;; $ s -match&quot;(?s)(。*)&lt; Foobar&gt;&quot ;; $ matches [1]
- perl -
s
修飾子(または開始時の(?s)
インラインバージョン)(デモ ):/(。*)&lt; FooBar&gt; / s
- python -
reを使用します。 DOTALL
(またはre.S
)フラグまたは(?s)
インライン修飾子(デモ):m = re.search(r&quot;(。*)&lt; FooBar&gt;&quot ;, s、flags = re.S)
(そして< code> if m:、print(m.group(1))
) - java -
Patternを使用します。 DOTALL
修飾子(またはインライン(?s)
フラグ)(デモ) :Pattern.compile(&quot;(。*)&lt; FooBar&gt;&quot ;, Pattern.DOTALL)
- groovy -
(? s)
パターン内修飾子(デモ):regex = /(?s)( 。*)&lt; FooBar&gt; /
- scala -
(?s)
修飾子(デモ):&quot;(?s)(。*)&lt; Foobar&gt;&quot; .r.findAllIn(&quot; abcde \ n fghij&lt; Foobar&gt;&quot ;)。matchData foreach {m =&gt; println(m.group(1))}
- javascript -
[^を使用]
または回避策[\ d \ D]
/[\ w \ W]
/[\ s \ S]
(< a href = "https://jsfiddle.net/36c6rt7o/3/" rel = "noreferrer">デモ):s.match(/([\ s \ S] *)&lt; FooBar&gt ; /)[1]
- c ++ (
std :: regex
)[\ s \ S]
またはJSの回避策(を使用しますデモ):regex rex(R&quot;(([\ s \ S] *)&lt; FooBar&gt;)&quot;);
- vba -と同じアプローチを使用JavaScript、
([\ s \ S] *)&lt; Foobar&gt;
。 - ruby -
/ m
MULTILINE 修飾子(デモ):s [/(.*)< Foobar&gt; / m、1]
- go -インライン修飾子
(?s)
開始時(デモ):re:= regexp.MustCompile( `(? s)(。*)&lt; FooBar&gt; `)
- swift -
dotMatchesLineSeparators
または(より簡単に)( ?s)
パターンのインライン修飾子:let rx =&quot;(?s)(。*)&lt; Foobar&gt;&quot;
- objective-c - Swiftと同様に、
(?s)
が最も簡単に機能しますが、オプションの使用方法:NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators error:&amp; regexError];
- re2 、 google-apps-script -
(?s)
修飾子( demo ):&quot;(? s)(。*)&lt; Foobar&gt;&quot;
(Googleスプレッドシートでは、= REGEXEXTRACT(A2、&quot;(?s)(。*)&lt; Foobar&gt;&quot;)
)
(?s)
に関する注意事項:
ほとんどの非POSIXエンジンでは、(?s)
インライン修飾子(または埋め込みフラグオプション)を使用して。
を強制的に改行に一致させることができます。
パターンの先頭に配置すると、(?s)
はパターン内のすべての。
の動作を変更します。 (?s)
が配置されている場合
JavaScriptでは、 / [\ S \ s] *&lt; Foobar&gt; /
を使用します。 ソース
([\ s \ S] *)&lt; FooBar&gt;
ドットは、改行(\ r \ n)を除くすべてに一致します。したがって、すべての文字に一致する\ s \ Sを使用します。
使用することもできます
(.*?\n)*?
貪欲な改行を含むすべてを一致させる
これにより、新しい行がオプションになります
(.*?|\n)*?
&quot;。&quot;
は通常、改行と一致しません。ほとんどの正規表現エンジンでは、&quot;。&quot;
も改行に一致します。
それが失敗した場合、 [\ S \ s]
のようなことをすることができます。
Eclipseの場合、次の式が機能しました:
フー
jadajada Bar&quot;
正規表現:
Foo[\S\s]{1,10}.*Bar*
/(.*)<FooBar>/s
sにより、ドット(。)が改行に一致します
Javaベースの正規表現では、 [\ s \ S]
(。| \ n)*
は、(たとえば) [\ s \ S] *
(言語の正規表現がこのようなエスケープをサポートしている場合) )を作る修飾子を指定する方法を見つけるよりも。改行にも一致します。または、 [[:space:] [:^ space:]] *
のようなPOSIXyの代替手段を使用できます。
RegexOptions.Singlelineを使用すると、の意味が変わります。改行を含める
Regex.Replace(content、searchText、replaceText、RegexOptions.Singleline);
解決策:
パターン修飾子sUを使用すると、PHPで目的のマッチングが取得されます。
例:
preg_match('/(.*)/sU',$content,$match);
出典:
http://dreamluverz.com/developers-tools/ regex-match-all-include-new-line http://php.net/manual/en/reference.pcre.pattern .modifiers.php
言語内で使用する場合、正規表現は行ではなく文字列に作用します。したがって、入力文字列に複数の行があると仮定して、正規表現を通常どおり使用できるはずです。
この場合、&quot;&lt; FooBar&gt;&quot;が指定されているため、指定された正規表現は文字列全体に一致します。存在します。正規表現の実装の詳細に応じて、$ 1の値(&quot;(。*)&quot;から取得)は、「fghij」またはまたは「abcde \ nfghij」。他の人が言ったように、一部の実装では、「。」改行と一致し、選択肢が与えられます。
ラインベースの正規表現の使用は、通常、egrepなどのコマンドライン用です。
私は同じ問題を抱えていて、おそらく最良の方法ではないが解決した。実際の試合をする前に、すべての改行を置き換えました。
mystring= Regex.Replace(mystring, "\r\n", "")
HTMLを操作しているので、この場合、改行はあまり重要ではありません。
上記のすべての提案を運良く試しましたが、.Net 3.5 FYIを使用しています
Javascriptでは、[^] *を使用して、改行を含むゼロから無限の文字を検索できます。
$("#find_and_replace").click(function() {
var text = $("#textarea").val();
search_term = new RegExp("[^]*<Foobar>", "gi");;
replace_term = "Replacement term";
var new_text = text.replace(search_term, replace_term);
$("#textarea").val(new_text);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="find_and_replace">Find and replace</button>
<br>
<textarea ID="textarea">abcde
fghij<Foobar></textarea>
一般的に。改行と一致しないため、((。| \ n)*)&lt; foobar&gt;
javaの特定のifブロックに一致させたい
...
...
if(isTrue){
doAction();
}
...
...
}
regExpを使用する場合
if \(isTrue(.|\n)*}
メソッドブロックの右中かっこが含まれているため、使用しました
if \(!isTrue([^}.]|\n)*}
ワイルドカードの一致から右中括弧を除外します。
多くの場合、サブストリングの前の行に散らばったいくつかのキーワードを使用してサブストリングを変更する必要があります。 xml要素を考えます:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
81を他の値、たとえば40に変更したいとします。最初に .UID.21..UID。
を識別し、次に \ n
.PercentCompleted。
まで。正規表現パターンと置換指定は次のとおりです。
String hw = new String("<TASK>\n <UID>21</UID>\n <Name>Architectural design</Name>\n <PercentComplete>81</PercentComplete>\n</TASK>");
String pattern = new String ("(<UID>21</UID>)((.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
String replaceSpec = new String ("$1$2$440$6");
//note that the group (<PercentComplete>) is $4 and the group ((.|\n)*?) is $2.
String iw = hw.replaceFirst(pattern, replaceSpec);
System.out.println(iw);
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>40</PercentComplete>
</TASK>
サブグループ(。| \ n)
はおそらく欠落しているグループ $ 3
です。 (?:。| \ n)
でキャプチャしないようにすると、 $ 3
は(&lt; PercentComplete&gt;)
になります。したがって、パターンと replaceSpec
は次のようにもなります。
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
そして交換は以前のように正しく動作します。