たとえば、この正規表現
(.*)<FooBar>
一致します:
abcde<FooBar>
しかし、どうすれば複数の行で一致させることができますか?
abcde
fghij<FooBar>
たとえば、この正規表現
(.*)<FooBar>
一致します:
abcde<FooBar>
しかし、どうすれば複数の行で一致させることができますか?
abcde
fghij<FooBar>
回答:
言語によって異なりますが、正規表現パターンに追加できる修飾子が必要です。PHPでは次のようになります。
/(.*)<FooBar>/s
の 末尾 sにより、ドットは改行を含むすべての文字に一致します。
s
修飾子をサポートしていません。代わりに、[^]*
同じ効果を実行します。
m
修飾子を使用します
これを試して:
((.|\n)*)<FooBar>
基本的には、「任意の文字または改行」が0回以上繰り返されます。
((.|\n|\r)*)<FooBar>
[\s\S]*
またはを使用し(?s).*
ます。
問題は、任意の文字を.
パターン一致できるかどうかです。答えはエンジンによって異なります。主な違いは、パターンがPOSIXまたは非POSIX正規表現ライブラリのどちらで使用されるかです。
特記 ルアパターン:正規表現とは見なされません.
が、POSIXベースのエンジンと同じように、そこの任意の文字と一致します。
もう一つのメモ MATLAB そして オクターブ:.
デフォルト(で任意の文字に一致するデモ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
(tokens
含まれているabcde\n fghij
項目)。
また、 ブーストの正規表現の文法は、デフォルトでドットが改行に一致します。BoostのECMAScript文法では、これをregex_constants::no_mod_m
(source)でオフにできます。
はどうかと言うと 神託(POSIXベース)、n
オプション(デモ)を使用:select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
POSIXベースのエンジン:
単なる.
改行はすでに一致しているため、修飾子を使用する必要はありません。バッシュ(デモ)。
の tcl(デモ)、postgresql(デモ)、r(TRE、ベースRのデフォルトエンジンなしperl=TRUE
、ベースRの場合、perl=TRUE
またはストリンガー / stringiパターンの場合は、(?s)
インライン修飾子を使用)(デモ)も.
同じ方法で処理します。
ただし、ほとんどのPOSIXベースのツールは、入力を1行ずつ処理します。したがって、.
スコープ外であるために改行と一致しません。これをオーバーライドする方法の例をいくつか示します。
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
(H;1h;$!d;x;
ファイルをメモリに丸呑みします)。行全体を含める必要がある場合は、sed '/start_pattern/,/end_pattern/d' file
(最初から削除すると一致する行が含まれて終了します)またはsed '/start_pattern/,/end_pattern/{{//!d;};}' file
(一致する行を除外して)を検討できます。perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
(-0
ファイル全体をメモリに丸呑みし、で-p
指定されたスクリプトを適用した後にファイルを印刷します-e
)。を使用-000pe
すると、ファイルが丸呑みされ、「段落モード」がアクティブになります。Perlは、連続する改行(\n\n
)をレコード区切りとして使用します。grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
。ここではz
、ファイルの丸呑みを(?s)
有効にし、.
パターンのDOTALLモードを(?i)
有効にし、大文字と小文字を区別しないモードを有効に\K
し、これまでに一致したテキストを省略し*?
、遅延量指定子であり、(?=<Foobar>)
以前の場所と一致します<Foobar>
。pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
(M
ここでファイルの丸呑みを有効にします)。Note pcregrep
はMac OS grep
ユーザーに適したソリューションです。非POSIXベースのエンジン:
s
修飾子PCRE_DOTALL修飾子:preg_match('~(.*)<Foobar>~s', $s, $m)
(デモ)RegexOptions.Singleline
フラグを使用(デモvar result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
インラインオプションを使用:$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
修飾子(または(?s)
最初にインラインバージョン)を使用します(デモ):/(.*)<FooBar>/s
re.DOTALL
(またはre.S
)フラグまたは(?s)
インライン修飾子(デモ)を使用します:(m = re.search(r"(.*)<FooBar>", s, flags=re.S)
そしてif m:
、print(m.group(1))
)Pattern.DOTALL
修飾子(またはインライン(?s)
フラグ)を使用します(デモ):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
パターン内修飾子を使用(デモ):regex = /(?s)(.*)<FooBar>/
(?s)
修飾子を使用(デモ):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
または回避策[\d\D]
/ [\w\W]
/ [\s\S]
(デモ):s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
)使用[\s\S]
またはJS回避策(デモ):regex rex(R"(([\s\S]*)<FooBar>)");
VBA vbscript-JavaScriptと同じアプローチを使用します([\s\S]*)<Foobar>
。(注:オブジェクトのMultiLine
プロパティは、
RegExp
誤って.
改行を越えた一致を許可するオプションと見なされることがありますが、実際には、JS正規表現の場合と同様に、文字列ではなく行の開始/終了に一致するように動作^
と$
動作のみが変更されます)動作。)
ルビー/m
-MULTILINE修飾子を使用(デモ):s[/(.*)<Foobar>/m, 1]
(?s)
:regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]
(デモ)stringr
/ stringi
ICU正規表現エンジンに電力が供給される正規表現funtions、また、使用(?s)
:stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]
(デモ)(?s)
最初にインライン修飾子を使用します(デモ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
か、または(より簡単に)(?s)
パターンに渡します。let rx = "(?s)(.*)<Foobar>"
(?s)
ですが、最も簡単に機能しますが、オプションの使用方法は次のとおりです。NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
修飾子を使用(デモ):("(?s)(.*)<Foobar>"
Googleスプレッドシート=REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)注意事項(?s)
:
ほとんどの非POSIXエンジンでは、(?s)
インライン修飾子(または埋め込みフラグオプション)を使用して強制的.
に改行を一致させることができます。
パターンの最初に配置した場合、パターン内(?s)
のすべての動作を変更.
します。(?s)
が先頭の後のどこかに配置されている場合、これがPythonに渡されたパターン.
でない限り、その右側にあるものだけが影響を受けre
ます。Python re
では、(?s)
場所に関係なく、パターン全体.
が影響を受けます。を使用すると、(?s)
効果が停止し(?-s)
ます。変更されたグループは、正規表現パターンの指定された範囲にのみ影響を与えるために使用できます(たとえばDelim1(?s:.*?)\nDelim2.*
、最初の.*?
一致は改行全体で行われ、2番目.*
は残りの行のみと一致します)。
POSIXノート:
非POSIX正規表現エンジンでは、任意の文字に一致させるために、[\s\S]
/ [\d\D]
/ [\w\W]
構成を使用できます。
[\s\S]
正規表現のエスケープシーケンスは角かっこ式内ではサポートされていないため、POSIXでは、(JavaScriptまたは非POSIXエンジンのように)はどの文字とも一致しません。[\s\S]
は、単一の文字、\
またはs
orに一致するブラケット式として解析されS
ます。
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
正規表現フラグの基本フラグ定義を設定して、それを反映します。そして、アービターは常にインライン修飾子です。どこに(?-sm)(?s).*
リセットされます。
.
そこの任意の文字(改行を含む)に一致します。このオンラインBashデモをご覧ください。
Go
回答に含めるための追加投票!
Eclipse検索を使用している場合は、「DOTALL」オプションを有効にして「。」を作成できます。行区切り文字を含む任意の文字に一致します。検索文字列の先頭に「(?s)」を追加するだけです。例:
(?s).*<FooBar>
(?s)
> =(?m)
([\s\S]*)<FooBar>
ドットは、改行(\ r \ n)を除くすべてに一致します。したがって、すべての文字に一致する\ s \ Sを使用します。
[text rangeOfString:regEx options:NSRegularExpressionSearch]
。ありがとう!
<FooBar>
"."
通常、改行は一致しません。ほとんどの正規表現エンジンでは、- S
フラグ(DOTALL
andとも呼ばれます)を追加して、改行にも一致SINGLELINE
させることができます"."
。それが失敗した場合、のようなことができます[\S\s]
。
/(.*)<FooBar>/s
sは、ドット(。)をキャリッジリターンと一致させます。
s
フラグはPCRE(PerlやPHPで利用可能)最も完全なエンジンに存在します。PCREには10個のフラグ(および他の多くの機能)がありますが、JavaScriptには3個のフラグ(gmi
)しかありません。
Javaベースの正規表現で使用できます [\s\S]
s
Javaでパターンにフラグを追加することができるため、JavaScriptにはs
フラグがありません。
パターン修飾子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
私は同じ問題を抱えており、おそらく最善の方法ではなくそれを解決しましたが、うまくいきます。実際の試合を行う前に、すべての改行を置き換えました。
mystring= Regex.Replace(mystring, "\r\n", "")
私はHTMLを操作しているので、この場合、改行は重要ではありません。
私は幸運なしに上記の提案をすべて試しました、私は.Net 3.5 FYIを使用しています
(\s|\S)
していて、私のためにトリックを行うようです!
(?s)
を.
一致させるために使用します。(\s|\S)
パフォーマンスが低下するので使用しないでください。
JavaScriptでは、[^] *を使用して、改行を含む0〜無限の文字を検索できます。
$("#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)*)<foobar>
\r
:((?:.|\r?\n)*)<foobar>
多くの場合、サブストリングの前の行にまたがるいくつかのキーワードを使用して、サブストリングを変更する必要があります。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
です (<PercentComplete>)
。したがって、パターンreplaceSpec
は次のようになります。
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
交換は以前と同じように正しく機能します。
通常、Powershellで3つの連続する行を検索すると、次のようになります。
$file = get-content file.txt -raw
$pattern = 'lineone\r\nlinetwo\r\nlinethree\r\n' # "windows" text
$pattern = 'lineone\nlinetwo\nlinethree\n' # "unix" text
$pattern = 'lineone\r?\nlinetwo\r?\nlinethree\r?\n' # both
$file -match $pattern
# output
True
奇妙なことに、これはプロンプトではUNIXのテキストになりますが、Windowsではファイル内のテキストになります。
$pattern = 'lineone
linetwo
linethree
'
行末を印刷する方法は次のとおりです。
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n