正規表現を貪欲にするにはどうすればよいですか?


227

私はjQueryを使用しています。特殊文字のブロック(開始と終了)を含む文字列があります。その特殊文字ブロックからテキストを取得します。文字列内検索には正規表現オブジェクトを使用しました。しかし、2つ以上の特殊文字がある場合、jQueryに複数の結果を見つけるように指示するにはどうすればよいですか?

私のHTML:

<div id="container">
    <div id="textcontainer">
     Cuc chiến pháp lý gia [|cơ thử|nghim|] th trường [|test2|đây là test ln 2|] chng khoán [|Mỹ|day la nuoc my|] và ngân hàng đầu tư quyn lc nht Ph Wall mi ch bt đầu.
    </div>
</div>

そして私のJavaScriptコード:

$(document).ready(function() {
  var takedata = $("#textcontainer").text();
  var test = 'abcd adddb';
  var filterdata = takedata.match(/(\[.+\])/);

  alert(filterdata); 

  //end write js 
});

私の結果は:[|cơthử|nghiệm|]thịtrường[| test2 |đâylàtestlần2 |]chứngkhoán[|Mỹ| day la nuoc my |]。しかし、これは私が望む結果ではありません:(。タイム1の[テキスト]とタイム2の[デモ]を取得する方法?


インターネットで情報を検索した後、仕事を終えたところです^^。私はこのようなコードを作成します:

var filterdata = takedata.match(/(\[.*?\])/g);
  • 私の結果は:[|cơthử|nghiệm|]、[| test2 |đâylàtestlần2 |] これは正しいです。しかし、私はこれを本当に理解していません。私の理由に答えてもらえますか?

回答:


492

貪欲でない正規表現の修飾子は、貪欲な対応部分に似ていますが、?すぐ後に続きます。

*  - zero or more
*? - zero or more (non-greedy)
+  - one or more
+? - one or more (non-greedy)
?  - zero or one
?? - zero or one (non-greedy)

29
?それ自体が「1または0」を意味することに注意してください(ただし、貪欲です!)。例えば'bb'.replace(/b?/, 'a') //'ab''bb'.replace(/c?/, 'a') //'abb'
Hashbrown

1
どのようにcはそこに何も一致しなかった
Muhammad Umer

1
私は彼がいるのでことを示唆していたと思い@MuhammadUmer c一致しませんが、あなたが持っている?、され0 or 1、一致するために起こっている0 number of c charactersので、それを置き換えます、。私が試したどの正規表現エンジンでもコンパイルされないため、どのように機能するかはわかりません。have
Noctis

35

あなたは貪欲が問題であることは正しいです:

--A--Z--A--Z--
  ^^^^^^^^^^
     A.*Z

両方を一致させたい場合A--Zは、使用する必要がありますA.*?Z(これ?により、*「消極的」または遅延になります)。

ただし、これを行うにはより良い方法がある場合があります。たとえば、

A[^Z]*+Z

これは、否定された文字クラスと所有的量指定子を使用してバックトラックを減らし、より効率的になる可能性があります。

あなたの場合、正規表現は次のようになります:

/(\[[^\]]++\])/

残念ながら、 Javascriptの正規表現は所有格指定子をサポートしていないため、次のようにする必要があります。

/(\[[^\]]+\])/

こちらもご覧ください


簡単な要約

*   Zero or more, greedy
*?  Zero or more, reluctant
*+  Zero or more, possessive

+   One or more, greedy
+?  One or more, reluctant
++  One or more, possessive

?   Zero or one, greedy
??  Zero or one, reluctant
?+  Zero or one, possessive

消極的で所有的な量指定子は有限繰り返しにも適用できることに注意してください {n,m}構造に。

Javaの例:

System.out.println("aAoZbAoZc".replaceAll("A.*Z", "!"));  // prints "a!c"
System.out.println("aAoZbAoZc".replaceAll("A.*?Z", "!")); // prints "a!b!c"

System.out.println("xxxxxx".replaceAll("x{3,5}", "Y"));  // prints "Yx"
System.out.println("xxxxxx".replaceAll("x{3,5}?", "Y")); // prints "YY"

私はあなたの正規表現を私の仕事にコピーし、結果は次のとおりです:無効な数量詞+ \])[このエラーで中断] var filterdata = takedata.match(/(\ [[^ \]] ++ \])/); \ n( firebugs + Firefox)何か問題がありますか?
Rueta

@Rueta:どうやらJavascriptフレーバーは所有格をサポートしていません。私はこの事実を反映するように私の回答を編集しました。+2 つではなく1つだけを使用できます。
polygenelubricants

1
アトミックグループは所有格指定子の代わりに使用できますが、JavaScriptはアトミックグループもサポートしていません。しかし、そこに第3の選択肢があり、この参照:instanceof.me/post/52245507631/... -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
ローランドPihlakas

2
これは、JavaScriptの質問に対するJavaの回答であり、Java!= JavaScriptです。読者、注意してください。
Roshambo 2017

3

こうなると思います

takedata.match(/(\[.+\])/g);

gそれは最初に一致した時点で停止しないように、最後には、グローバルな意味します。


ええ、あなたは/ gで正しいです。私はあなたの答え/ g ^^で私の仕事をしました。しかし、定期的に/(\[.+\])/gを作成すると、結果は次のようになります。[|cơthử|nghiệm|]thịtrường[| test2 |đâylàtestlần2 |]chứngkhoán[|Mỹ| day la nuoc my |] :(
Rueta
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.