2008-09-04 92 views
16

我正在尋找一個正則表達式,它將匹配以一個子串開頭並且不以特定子串結尾的字符串。正則表達式來匹配不是特定子串的東西

例子:

// Updated to be correct, thanks @Apocalisp 
^foo.*(?<!bar)$ 

應該匹配任何以 「foo」 的開頭,並且不能與 「酒吧」 結束。我知道[^ ...]語法,但是我找不到任何能夠爲字符串而不是單個字符做的事情。

我特意試圖爲Java的正則表達式做這件事,但我已經遇到過,所以其他正則表達式引擎的答案也會很好。

感謝@Kibbee驗證這是否也適用於C#。

+0

正如我下面提到 - 正則表達式中輸入字符串問題 「foo123bar」 它將匹配「foo12」 - 希望這是理想的行爲。 – Dmitry 2015-12-23 22:44:38

回答

9

我認爲在這種情況下,你想負回顧後,像這樣:

foo.*(?<!bar) 
1

我對Java正則表達式不熟悉,但Pattern Class的文檔建議您可以使用(?!X)作爲非捕獲零寬度負向預測(它在該事件中尋找不是X的東西,而不是將其作爲反向引用)。所以,你可以這樣做:

foo.*(?!bar) // not correct 

更新:Apocalisp的權利,你要負回顧後。 (你正在檢查什麼。*匹配不會以bar結尾)

+0

這個解決方案的問題在於,對於輸入字符串「foo123bar」它將匹配「foo12」 - 希望這是期望的行爲。 – Dmitry 2015-12-23 22:43:51

0

正如其他評論者所說,你需要一個負面預測。在Java中,你可以使用這個模式:

"^first_string(?!.?second_string)\\z" 
  • ^- 確保字符串 first_string
  • \ Z開始 - 手段 - 確保字符串second_string
  • 結束(second_string?!?)這first_string不能跟着second_string
1
使用

驗證@ Apocalisp的回答是:

import java.util.regex.Pattern; 
public class Test { 
    public static void main(String[] args) { 
    Pattern p = Pattern.compile("^foo.*(?<!bar)$"); 
    System.out.println(p.matcher("foobar").matches()); 
    System.out.println(p.matcher("fooBLAHbar").matches()); 
    System.out.println(p.matcher("1foo").matches()); 
    System.out.println(p.matcher("fooBLAH-ar").matches()); 
    System.out.println(p.matcher("foo").matches()); 
    System.out.println(p.matcher("foobaz").matches()); 
    } 
} 

此輸出正確的答案:

false 
false 
false 
true 
true 
true