最初の一致で停止する正規表現


531

私の正規表現パターンは次のようになります

<xxxx location="file path/level1/level2" xxxx some="xxx">

場所に割り当てられた見積もりの​​部分にのみ興味があります。貪欲なスイッチがなければ、以下のように簡単ではないでしょうか?

/.*location="(.*)".*/

動作していないようです。


あなたのソースは何ですか、それはHTMLかxmlか何かですか?
オスカーケリン

20
なぜこれはコミュニティーwikiなのですか?それは本当の質問です。今は遅すぎます。
Ahmad Mageed 2010年

1
何語で書いていますか?XMLには正規表現を使用しないでください。XMLを解析する方法は他にもたくさんあります
Oskar Kjellin

3
単純な属性をスキャンすることだけが目的ではありません。正規表現が適切で高速です。
codenheim、2011年

たとえばコードc#の場合、これにはlinqを使用する方がはるかに良いと思います。あなたが良いパーサーを持っているなら、正規表現の方が良いとは思えません
Oskar Kjellin

回答:


1096

正規表現は貪欲でないようにする必要があります。デフォルトで"(.*)"は、すべてに一致するためです"file path/level1/level2" xxx some="xxx"

代わりに、ドットスターを貪欲にしないようにすることができます。これにより、可能な限り少ない文字に一致します。

/location="(.*?)"/

?量指定子(?*または+)にを追加すると、貪欲ではなくなります。


32
FWIWは、少し異なるようにVIM、この正規表現のニーズを使用して、あなたを包みなさい:代わりに.*?それはだ.\{-}非欲張りマッチのために。
SooDesuNe 2011年

44
ダニエルに感謝します。「?を量指定子(?、*、または+)に追加すると、貪欲ではなくなります。」私にとって役立つヒントです。
PhatHV 2014

10
?これを理解しようとするときの私の混乱について説明します。どれほど適切か。
ロビー・スミス

1
私はあなたが「貪欲でない」の代わりに「怠惰な」と言うことができると信じています
マンティコア

50

location="(.*)"貪欲にしない限りlocation=、「後」から「後」まで一致しsome="xxxます。あなたのように、いずれかの必要性は、.*?交換するより良いか(つまりは、それが非貪欲作る).*[^"]*


3
[^ "] *は、現在のパターンの後のパターンをルックアップする必要がないため、おそらくほとんどの正規表現エンジンでより高速です
Jean Vincent

1
@キップ:あなたはおそらく正しいですが、.*?表記はより一般的です[^"]*
Bondax

[^ "] *を使用して区切り文字を含める場合はどうでしょうか
Frohlich

ここでは、^と[]の意味がわからない場合は、まったく違います。ほとんどの人は。*を理解するでしょう
Vincent Gerris

31

いかがですか

.*location="([^"]*)".*

これにより、。*による無制限の検索が回避され、最初の引用と完全に一致します。


移植性が懸念される場合は、grep不一致により、上記のパターンをお勧めします。
Josh Habdas

22

エンジンがサポートしている場合は、貪欲でないマッチングを使用します。?キャプチャ内。

/location="(.*?)"/

11

?答えは、グローバルフラグのないレイジー数量詞を使用することです。

例えば、

ここに画像の説明を入力してください

もしあなたがグローバルフラグを持っているなら/g、それは以下のようにすべての最短の長さのマッチと一致したでしょう。 ここに画像の説明を入力してください


1

定量化されたサブパターンを使用していて、Perl Docで説明されているように、

デフォルトでは、定量化されたサブパターンは「貪欲」です。つまり、パターンの残りの部分を一致させながら、(特定の開始位置を指定して)可能な限り何度も一致します。あなたはそれが必要な場合 最小回数と一致する可能性を、数量詞をたどる 「?」。意味は変わらず、「貪欲」だけであることに注意してください。

*?        //Match 0 or more times, not greedily (minimum matches)
+?        //Match 1 or more times, not greedily

したがって、定量化されたパターンを最小限に一致させるには、次のようにし?ます。

/location="(.*?)"/

1

ここに別の方法があります。

ここにあなたが欲しいものがあります。これは怠惰です[\s\S]*?

最初の項目: [\s\S]*?(?:location="[^"]*")[\s\S]*置換:$1

説明https : //regex101.com/r/ZcqcUm/2


完全を期すために、これは最後のものを取得します。これは貪欲です[\s\S]*

最後の項目:[\s\S]*(?:location="([^"]*)")[\s\S]* 置換:$1

説明https : //regex101.com/r/LXSPDp/3


これら2つの正規表現の違いは1つだけで、それは ?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.