正規表現を使用してサブストリング" It's big \"problem "
を取得するにはどうすればよいですか?
s = ' function(){ return " It\'s big \"problem "; }';
/"(?:[^"\\]|\\.)*"/
The Regex CoachおよびPCRE Workbenchで動作します。
JavaScriptでのテストの例:
var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
var m = s.match(/"(?:[^"\\]|\\.)*"/);
if (m != null)
alert(m);
これは、多くのLinuxディストリビューションで利用可能なnanorc.sampleからのものです。 Cスタイル文字列の構文強調表示に使用されます
\"(\\.|[^\"])*\"
EPharaohが提供するように、答えは
/"([^"\\]*(\\.[^"\\]*)*)"/
上記を単一引用符または二重引用符で囲まれた文字列に適用するには、次を使用します
/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/
ここで提供されるソリューションのほとんどは、代替繰り返しパス、つまり(A | B)*を使用します。
一部のパターンコンパイラは再帰を使用してこれを実装するため、大きな入力でスタックオーバーフローが発生する場合があります。
たとえば、Java: http://bugs.Java.com/bugdatabase/view_bug.do?bug_id=633799
次のようなもの:"(?:[^"\\]*(?:\\.)?)*"
、またはGuy Bedfordが提供するものは、ほとんどのスタックオーバーフローを回避する解析ステップの量を減らします。
"(?:\\"|.)*?"
\"
と.
を交互に使用すると、エスケープされた引用符が渡されますが、怠zyな量指定子*?
は、引用符で囲まれた文字列の終わりを超えないようにします。 .NET Framework REクラスで動作します
/"(?:[^"\\]++|\\.)*+"/
Perl 5.22.0がインストールされたLinuxシステムでman perlre
から直接取得。最適化として、この正規表現は+
と*
の両方の 'posessive'形式を使用してバックトラックを防止します。閉じ引用符のない文字列はいずれの場合も一致しないことが事前にわかっています。
これはPCREで完璧に動作し、StackOverflowに該当しません。
"(.*?[^\\])??((\\\\)+)?+"
説明:
"
で始まります。.*?
{Lazy match};エスケープ文字以外で終わる[^\\]
;(.*?[^\\])??
"
)で終わりますが、偶数個のエスケープ記号ペア(\\\\)+
を前に付けることができます。そして、それはGreedy(!)オプションです:((\\\\)+)?+
{Greedy matching}、bacause文字列は空でも、ペアの終了なしでもかまいません!/(["\']).*?(?<!\\)(\\\\)*\1/is
引用符で囲まれた文字列で動作するはずです
これは「」と「」の両方で機能するもので、最初に他のユーザーを簡単に追加できます。
( "| ')(?:\\\ 1 | [^\1])*?\ 1
最初のグループ( "または ')にあるものと完全一致する後方参照(\ 1)を使用します。
これまで触れられていないオプションは次のとおりです。
これには、エスケープされた開始タグを正しく一致させることができるという追加のボーナスがあります。
次の文字列があるとしましょう。 String \"this "should" NOT match\" and "this \"should\" match"
ここで、\"this "should" NOT match\"
は一致しないで、"should"
は一致する必要があります。その上で、this \"should\" match
は一致し、\"should\"
は一致しません。
最初の例。
// The input string.
const myString = 'String \\"this "should" NOT match\\" and "this \\"should\\" match"';
// The RegExp.
const regExp = new RegExp(
// Match close
'([\'"])(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))' +
'((?:' +
// Match escaped close quote
'(?:\\1(?=(?:[\\\\]{2})*[\\\\](?![\\\\])))|' +
// Match everything thats not the close quote
'(?:(?!\\1).)' +
'){0,})' +
// Match open
'(\\1)(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))',
'g'
);
// Reverse the matched strings.
matches = myString
// Reverse the string.
.split('').reverse().join('')
// '"hctam "\dluohs"\ siht" dna "\hctam TON "dluohs" siht"\ gnirtS'
// Match the quoted
.match(regExp)
// ['"hctam "\dluohs"\ siht"', '"dluohs"']
// Reverse the matches
.map(x => x.split('').reverse().join(''))
// ['"this \"should\" match"', '"should"']
// Re order the matches
.reverse();
// ['"should"', '"this \"should\" match"']
では、RegExpについて説明しましょう。これは、正規表現を3つの部分に簡単に分割できることです。次のように:
# Part 1
(['"]) # Match a closing quotation mark " or '
(?! # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\] # and a single escape
(?![\\]) # As long as that's not followed by an escape
)
# Part 2
((?: # Match inside the quotes
(?: # Match option 1:
\1 # Match the closing quote
(?= # As long as it's followed by
(?:\\\\)* # A pair of escape characters
\\ #
(?![\\]) # As long as that's not followed by an escape
) # and a single escape
)| # OR
(?: # Match option 2:
(?!\1). # Any character that isn't the closing quote
)
)*) # Match the group 0 or more times
# Part 3
(\1) # Match an open quotation mark that is the same as the closing one
(?! # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\] # and a single escape
(?![\\]) # As long as that's not followed by an escape
)
これはおそらく、画像形式でははるかに明確です: Jex's Regulex を使用して生成
github(JavaScript Regular Expression Visualizer)の画像 申し訳ありませんが、画像を含めるほどの評判はありませんので、現時点では単なるリンクです。
この概念を使用したもう少し高度なサンプル関数の要点を次に示します。 https://Gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js
regexpal でめちゃくちゃになり、この正規表現で終わりました:(どのように機能するかを聞かないでください、私はそれを笑って書いたことがほとんどわかりません)
"(([^"\\]?(\\\\)?)|(\\")+)+"
一部のファイルの解析を妨げる可能性のある引用文字列を削除しようとすると、同様の問題に直面しました。
私はあなたが思いつくことができる複雑な正規表現を打ち負かす2ステップのソリューションになりました:
line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful
読みやすく、おそらくより効率的です。
それが最初から検索される場合、これはうまくいくでしょうか?
\"((\\\")|[^\\])*\"
https://stackoverflow.com/a/10786066/1794894 のより広範なバージョン
/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/
このバージョンには
“
および閉じる”
)正規表現はすべての文字列yの特効薬ではないことを覚えておく必要があります。カーソルと線形の手動のシークを使用する方が簡単です。 CFL はかなり簡単にトリックを実行しますが、多くのCFL実装はありません(afaik)。