11

or繰り返しを許可せずに演算子を使用するにはどうすればよいですか?言い換えれば、正規表現:

(word1|word2|word3)+

一致 しますが、word1という単語が繰り返されているため、私がそれを望まないものにword1word2も一致します。word1word1どうすれば繰り返しを避けることができますか?

要約すると、私は次の主題を一致させたいと思います:

word1word2word3
word1
word2
word3word2

繰り返しがないため、すべてが一致することに注意してください。そして、私は次の主題が失敗することを望みます:

word1word2word1
word2word2
word3word1word2word2

編集

@Markのおかげで 私は知っています:

(?xi)

(?:  
        (?<A>word1|word2)(?!  .*  \k<A> )      # match for word1 or word2 but make sure that if you capture it it does not follow what it was just captured
    |   (?<B>word3|word4)(?!  .*  \k<B> )
)+

グループAまたはBで何かがキャプチャされたかどうかを確認することに興味があるからです。

4

4 に答える 4

8

あなたは否定的な先読みを使うことができます:

^(?:word1(?!.*word1)|word2(?!.*word2)|word3(?!.*word3))+$

オンラインで動作することを確認してください:rubular

于 2013-02-06T23:12:21.130 に答える
4

先読みソリューションが機能しない場合もあります。次のような構成を使用することで、ルックアラウンドなしでこれを適切に解決できます。

(?:(?(1)(?!))(word1)|(?(2)(?!))(word2)|(?(3)(?!))(word3))+

これは、一部の単語が他の単語の部分文字列である場合でも機能し、より大きな文字列の一致する部分文字列を検索する場合にも機能します(文字列全体に一致するだけではありません)。

ライブデモ

によって行われた以前に一致した場合は、変更に失敗するだけで機能し(?(1)(?!))ます。(?(1)foo)は条件付きであり、fooグループ1が以前に一致した場合は一致します。(?!)常に失敗します。

于 2013-02-06T23:49:51.743 に答える
0

Byersのソリューションはハードコーディングされすぎており、文字が増えると非常に面倒になります。単純に正規表現で重複一致を探してみませんか?

([^\d]+\d)+(?=.*\1)

それが一致する場合、その一致はパターンに繰り返しが見つかったことを意味します。一致が機能しない場合は、有効なデータセットがあります。

于 2013-02-06T23:50:27.130 に答える
0

後方参照を含む否定的な先読みを使用できます。

^(?:(word1|word2|word3)(?!.*\1))+$

ここ\1で、はキャプチャグループの一致を示し(word1|word2|word3)ます。

これは、に文字を追加することによって形成することはできず、またはに文字を追加することによってword2形成することはできないと想定していることに注意してください。word1word3word1word2

于 2013-02-06T23:52:30.093 に答える