2011-03-25 75 views
1

大家好:我試圖使用零寬度斷言負向前瞻來匹配包含字符串「abc」的字符串,而這個是我得到:使用零寬度斷言負向前瞻來匹配一個包含字符串「abc」的字符串

Pattern pattern = new Perl5Compiler().compile("((?!abc).)+"); 
    Perl5Matcher matcher = new Perl5Matcher(); 
    System.out.println(matcher.matches("abc", pattern)); 
    System.out.println(matcher.matches("abdas dfas", pattern)); 
    System.out.println(matcher.matches("d abc ", pattern)); 
    System.out.println(matcher.matches("fafabcdef", pattern)); 

,其結果是:

false 
    true 
    false 
    false 

什麼我不明白的是,爲什麼字符串「abc」不匹配,它不包含任何後字符斷言「abc」。任何人都可以請弄清楚這是如何工作的? tks〜

回答

4

瀏覽者開始在位置上做他們的事情,而不是在角色上。所以,與字符串​​,這部分你的正則表達式:(?!abc).開始展望位置"a"在您的字符串。該位置是"a"之前的空字符串。這就是爲什麼它無法匹配。

+0

感謝您的回答,Bart!那麼第二個字符串「abdasdfas」呢?根據你的說法,這將不能匹配。 – khotyn 2011-03-25 07:14:34

+0

@khotyn,no,在字符串'「abdasdfas」'沒有位置(空字符串),在它的前面有子字符串'「abc」',以便字符串匹配。 – 2011-03-25 07:19:27

+0

再次感謝,我想我知道了,第一個字符串失敗,因爲在「a」之前的空字符串後面有一個子字符串「abc」,因此匹配失敗。關鍵是'(?!abc).'在空字符串之後向前看'abc'。 – khotyn 2011-03-25 07:31:49

1

嗯,這與Perl5的實際工作方式有所不同。

$ perl -E' 
    for ("abc", "abdas dfas", "d abc ", "fafabcdef") { 
     say "$_: ", /((?!abc).)+/ ? "true ($&)" : "false"; 
    } 
' 
abc: true (bc) 
vabdas dfas: true (abdas dfas) 
d abc : true (d) 
fafabcdef: true (faf) 

它必須有一個隱含的^和\ z。

$ perl -E' 
    for ("abc", "abdas dfas", "d abc ", "fafabcdef") { 
     say "$_: ", /^((?!abc).)+\z/ ? "true ($&)" : "false"; 
    } 
' 
abc: false 
abdas dfas: true (abdas dfas) 
d abc : false 
fafabcdef: false 

因匹配/ abc /的某些位置而不匹配的那些。

+0

Java的「own」'matches()'方法驗證/匹配整個字符串,所以它確實具有隱式錨點。我猜想OP的(非標準)'Perl5Matcher'類也有它們。 – 2011-03-25 20:06:20

相關問題