2017-02-27 61 views
2

我試圖檢查每一行是否等於「測試」。當我嘗試運行下面的代碼時,我期望結果是真實的,因爲每一行都完全是「測試」。但結果是錯誤的。java - 意外的結果在正則表達式匹配

// Expected outcome: 
// "test\ntest\ntest" - should match 
// "test\nfoo\ntest" - should not match 
// "test\ntesttest\ntest" - should not match 

Pattern pattern = Pattern.compile("^test$", Pattern.MULTILINE); 
Matcher matcher = pattern.matcher("test\ntest"); 

System.out.println(matcher.matches()); // result is false 

我在這裏錯過了什麼?爲什麼結果是錯誤的?

+0

正如喬說,你的正則表達式只匹配了一個字「測試」,因爲它在測試這個詞測試線和結束的開始。 –

回答

1

Pattern.compile("^test$", Pattern.MULTILINE),你只要求正則表達式引擎匹配一條單一的行等於test。當使用Matcher#matches()時,您告訴正則表達式引擎匹配完整的字符串。由於您的字符串不等於test,因此您將得到false

爲了驗證包含都等於test線串,你可以使用

Pattern.compile("^test(?:\\Rtest)*$") 

在舊的Java版本,則需要使用\n\r?\n更換\R(任何換行符)。

online demo

Pattern pattern = Pattern.compile("^test(?:\\Rtest)*$"); 
Matcher matcher = pattern.matcher("test\ntest"); 
System.out.println(matcher.matches()); // => true 
2

由於您使用的是Pattern.MULTILINE,因此它與整個字符串test\ntest相匹配。但在你的正則表達式中,你指定該字符串應該只包含一個test的實例,因爲它被開始和結束的錨所包圍。

0

Pattern.MULTILINE讓您的正則表達式來之前和行分隔符,這是不是默認的行爲後,匹配^$。默認值僅在輸入的開始和結束時匹配。

但是,如果使用matches(),它會嘗試將正則表達式與整個輸入文本相匹配,從而產生false,因爲輸入不等於"test"

雖然matches()不起作用,但您可以使用find()來查找與正則表達式匹配的輸入的子序列。由於^$匹配\n之前和之後,您的模式會查找兩個子序列。

但這只是我的兩美分。

Pattern pattern = Pattern.compile("^test$", Pattern.MULTILINE); 
Matcher matcher = pattern.matcher("test\ntest"); 

System.out.println(matcher.matches()); // prints "false", the whole input doesn't match a single "test" 

System.out.println(matcher.find()); // prints "true" 
System.out.println(matcher.group()); // prints "test" 

System.out.println(matcher.find()); // prints "true" 
System.out.println(matcher.group()); // prints "test" 

System.out.println(matcher.find()); // prints "false" 
+0

在這種情況下,爲什麼會使用Pattern.MULTILINE進行matches()檢查? – XLordalX

+0

@XLordalX你不會。一個使用find()來確保相同輸入中的每一行都以給定的模式開始或結束。 –