2016-05-10 45 views
0
String str = " foo"; 
System.out.println(str.matches("\\s*foo")); //false 
System.out.println(Arrays.toString(str.getBytes()));//[-30, -128, -123, 102, 111, 111] 

從上面,第一個字符不是space混淆java替換的結果當匹配空格的字符串開始

String replaceStr = str.replaceAll(".*?([a-z]*)", "$1"); 
System.out.println(replaceStr.equals("foo"));//false 

上面的代碼只能得到foo

replaceStr = str.replaceAll("^.*?([a-z]*)$", "$1"); 
System.out.println(replaceStr.equals("foo"));//true 

爲什麼有^$,然後才能得到的只有foo

+3

我複製/粘貼了你的字符串,第一個字符是'\ u2005' - * 2005 FOUR-PER-EM SPACE *。它屬於'\ p {Zs}'類別。好像你只需要'(?U)\\ s * foo'。請參閱[本演示](https://ideone.com/URLzgC) –

+0

@WiktorStribiżew謝謝,讓我知道這些知識。 – zhuguowei

+0

@WiktorStribiżew,但你怎麼知道'-30,-128,-123'是'\ u2005' – zhuguowei

回答

5

.*?非貪婪—它會嘗試儘可能少的匹配,同時仍然有整體匹配成功。

由於[a-z]*可以匹配零封,.*?([a-z]*)可以成功匹配位置0空字符串所以,這就是它的作用。

通過追加$,你迫使正則表達式一直延伸到字符串的末尾(如果可能的話),所以.*?儘可能匹配,以使其成爲可能。

你也可以通過編寫[a-z]+代替[a-z]*完成同樣的事情,因爲這將迫使.*?遠不足以讓[a-z]+比賽至少有一個字母相匹配。

但是,最好的辦法可能是寫:

replaceStr = str.replaceFirst("^[^a-z]*", ""); 

這相當於你的工作的例子,但更清晰。 ([^a-z]的意思是「除a-z之外的任何字符」。)