4

Perlの負の先読み正規表現を使用して、ターゲットの文字列から特定の文字列を除外しようとしています。アドバイスをお願いします。

-sm、-sp、または-saを含まない文字列を取得しようとしました。

正規表現:

hostname .+-(?!sm|sp|sa).+

入力

hostname 9amnbb-rp01c
hostname 9tlsys-eng-vm-r04-ra01c
hostname 9tlsys-eng-vm-r04-sa01c
hostname 9amnbb-sa01
hostname 9amnbb-aaa-sa01c

期待される出力:

hostname 9amnbb-rp01c              - SELECTED
hostname 9tlsys-eng-vm-r04-ra01c   - SELECTED 
hostname 9tlsys-eng-vm-r04-sa01c
hostname 9amnbb-sa01
hostname 9amnbb-aaa-sa01c

ただし、この実際の出力は次のとおりです。

hostname 9amnbb-rp01c              - SELECTED
hostname 9tlsys-eng-vm-r04-ra01c   - SELECTED
hostname 9tlsys-eng-vm-r04-sa01c   - SELECTED
hostname 9amnbb-sa01
hostname 9amnbb-aaa-sa01c          - SELECTED

私を助けてください。

ps: 結果を視覚化するために正規表現コーチを使用しました。

4

2 に答える 2

4

.+-先読みの内側を移動します。

hostname (?!.+-(?:sm|sp|sa)).+

Rubular:http ://www.rubular.com/r/OuSwOLHhEy

.+-が先読みの外側にある場合、先読みによって正規表現が失敗しなくなるまでバックトラックできるため、現在の式は正しく機能していません。たとえば、文字列hostname 9amnbb-aaa-sa01cと正規表現を使用hostname .+-(?!sm|sp|sa).+すると、最初の文字.+が一致9amnbbし、先読みがaa次の2文字と見なされて続行され、2番目の文字列が.+一致しaaa-sa01cます。

私の現在の正規表現に代わるものは次のとおりです。

hostname .+-(?!sm|sp|sa)[^-]+?$

これにより、先読みの後に発生する可能性がないため、バックトラックが防止されます。これは、複数行のグローバルモードで正しく機能するように、-貪欲でないものが使用されます。?

于 2012-06-06T17:10:02.670 に答える
1

以下はテストケースに合格します。

hostname [^-]+(-(?!sm|sp|sa)[^-]+)+$

FJさんの回答より少し読みやすいと思います。

ルディに答えるために: 質問は、ケースの除外状況として提起されました. それは否定的な先読みによく合っているようです。:)

于 2012-06-06T17:28:45.837 に答える