5

ruby 2.1 を使用していますが、同じことが rubular サイトで複製できます。

これが私の文字列の場合:

儘管中國婦幼衛生監測辦公室制定的

そして、次の式で正規表現一致を行います。

(中國婦幼衛生監測辦公室制定|管中)

より長いトークンを一致として取得することを期待しています。

中國婦幼衛生監測辦公室制定

代わりに、一致として 2 番目の代替を取得します。

私の知る限り、漢字でないときはそのように機能します。

これが私の文字列の場合:

foobar

そして、私はこの正規表現を使用します:

(foobar|foo)

返された一致結果はfoobarです。順序が逆の場合、一致する文字列はfoo. それは私には理にかなっています。

4

1 に答える 1

15

正規表現がより長い代替に一致するというあなたの仮定は正しくありません。

少し時間があれば、正規表現がどのように機能するかを見てみましょう...

簡単な復習: 正規表現のしくみ: ステート マシンは常に左から右に読み取り、必要に応じてバックトラックします。

2 つのポインターがあり、1 つはパターン上にあります。

(cdefghijkl|bcd)

あなたの文字列のもう一方:

abcdefghijklmnopqrstuvw

String 上のポインタは左から移動します。戻ることができるとすぐに、次のようになります

バツ
(出典:gyazo.com

理解するために、これをより「連続した」シーケンスに変えてみましょう。

y
(出典:gyazo.com

あなたのfoobar例は別のトピックです。この投稿で述べたように:

正規表現の仕組み: ステート マシンは常に左から右に読み取ります。,|,, == ,、常に最初の代替にのみ一致するためです。

    いいですね、Unihedron ですが、最初の交替に強制するにはどうすればよいですか

見て!*

^(?:.*?\Kcdefghijkl|.*?\Kbcd)

ここにregex demoがあります。

この正規表現は、最初に文字列全体を最初の代替と一致させようとします。完全に失敗した場合にのみ、2 番目の代替との一致を試みます。\Kここでは、constructの背後にあるコンテンツとの一致を維持するために使用されます。\K


*: \KRuby では 2.0.0 からサポートされていました。

続きを読む:





ああ、退屈だったので、正規表現を最適化しました。

^(?:(?:(?!cdefghijkl)c?[^c]*)++\Kcdefghijkl|(?:(?!bcd)b?[^b]*)++\Kbcd)

ここでデモを見ることができます。

于 2014-08-26T17:19:48.897 に答える