0

正規表現を書き込もうとすると 、両側にちょうど3つの大文字を持つすべての文字が見つかります

次の正規表現は、文字の左側に大文字が 3 つ、右側に3 つ(またはそれ以上)あるすべての文字を検索します。

'(?<![A-Z])[A-Z]{3}(.)(?=[A-Z]{3})'

正規表現を使用して右側を 3 つ以下の大文字に制限しようとする場合:

'(?<![A-Z])[A-Z]{3}(.)(?=[A-Z]{3})(?![A-Z])'

結果が得られません。最初の正規表現に (?![AZ]) を追加すると失敗するようです。

誰かが私に問題を説明し、それを解決する方法を提案できますか?

ありがとう。

4

4 に答える 4

1

肯定的な先読みのに否定的な先読みを入れる必要があります。

(?<![A-Z])[A-Z]{3}.(?=[A-Z]{3}(?![A-Z]))

後読みでもそれを行うことができます:

(?<=(?<![A-Z])[A-Z]{3}).(?=[A-Z]{3}(?![A-Z]))

ルックアラウンド自体は文字を消費しないため、「固定長の後読み」ルールに違反しません。


編集(固定長の後読みについて):後読みをサポートするすべてのフレーバーの中で、Python は最も柔軟性がありません。ほとんどのフレーバー (Perl、PHP、Ruby 1.9+ など) では、次を使用できます。

(?<=^[A-Z]{3}|[^A-Z][A-Z]{3}).

...正確に 3 つの大文字の ASCII 文字が前にある文字に一致します。最初の選択肢 - - 3ポジション後ろ^[A-Z]{3}を探し始めるのに対し、2 番目 - - は正確に4ポジション戻る。Java では、これを次のように減らすことができます。[^A-Z][A-Z]{3}

(?<=(^|[^A-Z])[A-Z]{3}).

...コンパイル時に少し余分な作業を行って、後読みの最大長が 4 桁になることを確認するためです。そして、.NET と JGSoft では何でもありです。どこでも合法であれば、後読みでも合法です。

しかし、Python では、後読み部分式は単一の固定数の文字と一致する必要があります。その制限に何度か頭をぶつけたことがあれば、次のようなことがうまくいくとは思わないかもしれません。

(?<=(?<![A-Z])[A-Z]{3}).

少なくとも私はしませんでした。Java バージョンよりもさらに簡潔です。Pythonでどのように機能しますか? しかし、Python や、後読みをサポートする他のすべてのフレーバーでは機能します。

いいえ、どんなフレーバーでも先読みに同様の制限はありません。

于 2012-05-25T21:20:24.067 に答える
0

前向きな先読みを取り除くことは私にとってうまくいきました。

(?<![A-Z])[A-Z]{3}(.)([A-Z]{3})(?![A-Z])

'ABCdDEF' 'ABCfDEF' 'HHHhhhHHHH' 'jjJJjjJJJ' JJJjJJJ は ABCdDEF ABCfDEF JJJjJJJ に一致します。

于 2012-05-25T20:25:44.923 に答える
0

正規表現エンジン複数の先読みアサーションでどのように機能するかはわかりませんが、使用しているエンジンはそれについて独自の意見を持っている可能性があります。

次のように、単一のアサーションを使用することもできます。

 '(?<![A-Z])[A-Z]{3}(.)(?=[A-Z]{3}[^A-Z])'

後読みと同じ:

 '(?<=[^A-Z][A-Z]{3})(.)(?=[A-Z]{3}[^A-Z])'

これにより、行頭と行末のパターンの一致に問題が生じます。適切な解決策は思いつきませんが、汚いトリックがある可能性があります。たとえば、行全体の最初と最後にスペース (または何か他のもの) を追加してから、マッチングを実行します。

$ echo 'ABCdDEF ABCfDEF HHHhhhHHHH AAAaAAAbAAA jjJJJJjJJJ JJJjJJJ' | sed 's/.*/ & /' | grep -oP '(?<=[^A-Z][A-Z]{3})(\S)(?=[A-Z]{3}[^A-Z])'
d
f
a
b
j

(.)真ん中に変更したことに注意してください(\S)。スペースを一致させたい場合は元に戻してください。

PS Python Challengeを解決していますか? :)

于 2012-05-25T20:26:16.873 に答える
0

先読みパターンは後読みパターンと同じなので、 continue アンカーを使用することもできます\G:

/(?:[A-Z]{3}|\G[A-Z]*)(.)[A-Z]{3}/

3 つの大文字が 1 つの文字の前にある場合、または最後の一致が中断された場合 (オプションで他の大文字が続く場合)、一致が返されます。

于 2012-05-26T07:11:05.027 に答える