2016-06-28 5 views
1

文字の最後の部分が-notmeに一致しない限り、大括弧(大括弧で囲まれた文字)と大括弧([^\[\]]+)のいずれかを一致させようとしています。perl正規表現否定セットがネガティブ先読みで一致する

-bash-4.2# cat /tmp/input 
[test-ing] 
yes 
yes 
no 
maybe 

[test-ing-notme] 
yes 
yes 
no 
maybe 

しかし、私の出力は次のようになります:

perl -sp -e 'if (/\[[^\[\]]+?(?!-notme)\]$/../^no/) 
{ print "#"; s/^yes/$VAR/; }' -- -VAR="CHANGED" /tmp/input 

私の入力ファイルは、次のようになります

#[test-ing] 
#CHANGED 
#CHANGED 
#no 
maybe 

#[test-ing-notme] 
#CHANGED 
#CHANGED 
#no 
maybe 

私の推測では、負のセットが私の否定先読みではないがどうあるべきか、一致していることですそれで、ネガティブセットの遅延マッチングによる私の試みですが、結果は貪欲なマッチの場合と同じです。あなたは、パターン変更する必要があります

#[test-ing] 
#CHANGED 
#CHANGED 
#no 
maybe 

[test-ing-notme] 
yes 
yes 
no 
maybe 

答えて

2

::私の期待は、出力は次のようになりますということでしょう

/\[[^\[\]]+?(?!-notme)\]$/このように

/\[[^]]++(?<!-notme)]$/ 
# ^^-------------- a negative loobehind before the closing bracket 
#  '---------------- a possessive quantifier to prevent backtracking 

には、あなたが "-notme" ISNと確信しています文字列の無駄な位置でテストされていません。

文字クラスの最初の位置にある場合、またはネゲーションキャレットの直後にある場合は、文字クラスの閉じ括弧をエスケープすることはできません。

+0

こんにちはカシミール、なぜ\ {(?:[^]] +?(?<! - notme)\]) 'も動作しますか? '++'の代わりに、 '+?'の違いは何ですか?ちょうど私がhttps://regex101.com/r/sV5gF7/1でテストしていたので、ちょっと面白かったよ。 –

+2

@JorgeCampos: '[^]] +'もうまくいきますが、唯一の違いはパフォーマンスです。怠惰な量指定子では、 '[^]] +?' *で取られた各文字についてlookbehindがテストされます(lookbehindが成功するまで、各文字に対して次のトークン ']'は最後を除くと失敗します)*、正規表現エンジンはパターンを成功させるためにバックトラックしようとします。しかし、所有量限定子、選択肢なしでは、すべての文字が取られ、正規表現エンジンはバックトラックする権利がありません。 –

+0

大きな説明。ありがとうございました。 –