これは明らかに単純化されたケースですが、必要なのは、 に一致しないが ( が続かない)aabb|bbaa
に対しては正常に機能する正規表現です。aabb
|...
のような正規表現[ab]+(?!\|[ab]+)*
はかなり近いですが、それでもaabb
から一致しますが、その場合はまったく一致しaabb|bbaa
たくありません。
文字列の開始 ( ^
) および文字列の終了 ( $
) アンカーの使用は許可されていません。
これは明らかに単純化されたケースですが、必要なのは、 に一致しないが ( が続かない)aabb|bbaa
に対しては正常に機能する正規表現です。aabb
|...
のような正規表現[ab]+(?!\|[ab]+)*
はかなり近いですが、それでもaabb
から一致しますが、その場合はまったく一致しaabb|bbaa
たくありません。
文字列の開始 ( ^
) および文字列の終了 ( $
) アンカーの使用は許可されていません。
すべてを 1 つの正規表現で表現しなければならないというルールはありません。また、コードが読めなくなります。私は次のようなものを提案します
not (matches "aabb\|bbaa") and (matches "aabb")
あなたが主張するなら、あなたは使うことができます
([ab]+)(\|[ab]+)*
2 番目のグループが空でない場合は一致を破棄します。
実際には、何らかの方法で先読みにアンカーが必要です
[ab]+(?=[^ab]*\z)
より一般的には、a
とb
は任意の部分式であり、次のものが必要です。
(?:a|b)+(?=(?s:(?!a)(?!b).)*\z)
読みやすさと保守性のために、常に/x
モードで記述する必要があります。
(?x) # enable white space and comments
(?: a # any a
| b # or b
) + # repeated once or more, preferring more
# now a lookahead assertion
(?=
(?s: (?!a) # not a coming right up at this point
(?!b) # nor b coming right up at this point
. # any single code point
) * # repeated zero or more times
\z # anchored to the end of the string
)