私は非常によく似た投稿を見つけましたが、私の正規表現をここで得ることはできません。
私は他の2つの文字列の間にある文字列を返す正規表現を書き込もうとしています。たとえば、次のようにします。文字列 "cow"と "milk"の間にある文字列を取得します。
私の牛はいつも牛乳をくれる
戻る
「いつでも」
これが私がこれまでにつなぎ合わせた表現です。
(?=cow).*(?=milk)
しかし、これは文字列 "cow always gives"を返します
先読み(その(?=
部分)は入力を消費しません。これは幅ゼロのアサーションです(境界チェックと後書きも同様です)。
cow
の部分を消費するには、ここで通常の一致が必要です。その間の部分をキャプチャーするには、キャプチャー・グループを使用します(キャプチャーしたいパターンの部分を括弧内に入れてください)。
cow(.*)milk
先読みはまったく必要ありません。
Javascriptで2つの文字列の間の文字列を取得するための正規表現
ほとんどの場合にうまくいく最も完全な解決策は、キャプチャグループとlazy dot matchingを使うことです。パターンただし、JS正規表現のドット.
は改行文字と一致しないため、100%の場合に機能するのは[^]
または[\s\S]
/[\d\D]
/[\w\W]
の構文です。
ECMAScript 2018をサポートするJS環境では、s
name__修飾子は.
が改行文字を含む任意の文字と一致することを可能にし、regexエンジンは可変長の後書きをサポートします。だから、あなたはのような正規表現を使用することができます
var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional
どちらの場合も、cow
name__の後に1/0以上の空白があるcow
name__について現在位置がチェックされ、その後、可能な限り少ない0+文字が一致して消費され(=一致値に追加され)、milk
name__がチェックされます。 (このサブストリングの前に1/0以上の空白がある場合)。
これ以降のシナリオはすべてのJS環境でサポートされています。答えの下部にある使用例を参照してください。
cow (.*?) milk
最初にcow
name__が見つけられ、次にスペース、そして*?
が怠惰な量指定子である限りできるだけ少ない改行以外の0+文字がグループ1に取り込まれ、それからmilk
name__を伴うスペースが続く必要があります。 消費されました。
cow ([\s\S]*?) milk
ここでは、最初にcow
name__とスペースがマッチングされ、次に、可能な限り少ない0+文字がマッチングされてグループ1に取り込まれ、次にmilk
name__を持つスペースがマッチングされます。
>>>15 text>>>67 text2>>>
のような文字列があり、その間に>>>
+ number
name __ + whitespace
name__と>>>
の間で2つの一致を取得する必要がある場合、 />>>\d+\s(.*?)>>>/g
を使用することはできません。 >>>
より前の67
は、最初の一致が見つかった時点ですでに消費されています。あなたはそれを実際に「ぐらつかせる」ことなくテキストの存在をチェックするために 前向きな先読み を使うことができます(すなわちマッチに追加する) :
/>>>\d+\s(.*?)(?=>>>)/g
グループ1の内容が見つかった場合の online regex demo y yield text1
およびtext2
を参照してください。
文字列について可能性のあるすべての重なり合う一致を取得する方法 も参照してください。
非常に長い入力が与えられると、正規表現パターン内の遅延ドットマッチングパターン(.*?
)はスクリプトの実行を遅くするかもしれません。多くの場合、 ループを展開する手法 が役立ちます。 "Their\ncow\ngives\nmore\nmilk"
からcow
name__とmilk
name__の間をすべて取得しようとすると、milk
name__で始まらないすべての行と一致させる必要があることがわかります。したがって、 cow\n([\s\S]*?)\nmilk
の代わりに使用できます。
/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm
regex demo を参照してください(\r\n
がある場合は、/cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
を使用してください)。この小さなテスト文字列ではパフォーマンスの向上はごくわずかですが、非常に大きなテキストでは違いがわかります(特に行が長く改行がそれほど多くない場合)。
JavaScriptでの正規表現の使用例
//Single/First match expected: use no global modifier and access match[1] console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]); // Multiple matches: get multiple matches with a global modifier and // trim the results if length of leading/trailing delimiters is known var s = "My cow always gives milk, thier cow also gives milk"; console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);})); //or use RegExp#exec inside a loop to collect all the Group 1 contents var result = [], m, rx = /cow (.*?) milk/g; while ((m=rx.exec(s)) !== null) { result.Push(m[1]); } console.log(result);
これは牛と牛乳の間にあるものをつかむ正規表現です(前後のスペースなしで):
srctext = "My cow always gives milk.";
var re = /(.*cow\s+)(.*)(\s+milk.*)/;
var newtext = srctext.replace(re, "$2");
.*
をキャプチャする必要があります.*
を不一致にすることができます(しかしそうする必要はありません)先読みの必要はまったくありません。
> /cow(.*?)milk/i.exec('My cow always gives milk');
["cow always gives milk", " always gives "]
以下のMartinho Fernandesのソリューションを使用して、必要なものを入手できました。コードは次のとおりです。
var test = "My cow always gives milk";
var testRE = test.match("cow(.*)milk");
alert(testRE[1]);
TestRE変数を配列として警告していることに気付くでしょう。これは、何らかの理由でtestREが配列として返すためです。からの出力:
My cow always gives milk
変更点:
always gives
次の正規表現を使うだけのことです。
(?<=My cow\s).*?(?=\smilk)
メソッドmatch()は、文字列から一致するものを検索し、Arrayオブジェクトを返します。
// Original string
var str = "My cow always gives milk";
// Using index [0] would return<br/>
// "**cow always gives milk**"
str.match(/cow(.*)milk/)**[0]**
// Using index **[1]** would return
// "**always gives**"
str.match(/cow(.*)milk/)[1]