将字符串开头与空格匹配时java replaceAll的正则表达式混淆结果
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
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
# 1 楼答案
.*?
是非贪婪的-它将尝试尽可能少地匹配,同时仍保持整体匹配成功由于
[a-z]*
可以匹配零个字母,因此.*?([a-z]*)
可以成功匹配位置0处的空字符串。这就是它的作用通过附加
$
,您将强制正则表达式一直扩展到字符串的末尾(如果可能的话),因此.*?
尽可能匹配,以便实现这一点你也可以通过写
[a-z]+
而不是[a-z]*
来完成同样的事情,因为这将迫使.*?
匹配足够远,以使[a-z]+
至少匹配一个字母但最好的方法可能是写:
这相当于你的工作示例,但更清楚。(
[^a-z]
表示“除a–z之外的任何字符”。)