正则表达式否定[^is]未生效及匹配差异问题咨询
正则表达式匹配疑问解答
先看你给出的代码:
String text = "$.example(\"This is the tes't\")"; final String quoteRegex = "example.*?(\"[^is].*?\")"; Matcher matcher0 = Pattern.compile(quoteRegex).matcher(text); while (matcher0.find()) { System.out.println(matcher0.group(1)); }
第一个问题:为什么正则中的[^is]没有阻止匹配?
你可能误解了否定字符类[^is]的作用——它只匹配单个字符,意思是"匹配一个既不是i也不是s的字符",而不是"匹配不包含i和s的整个字符串"。
回到你的正则example.*?("[^is].*?"):
example.*?会惰性匹配到第一个双引号前的内容(也就是example();- 接下来的
"[^is]"部分,双引号后的第一个字符是T,它既不是i也不是s,完全符合[^is]的匹配规则; - 最后
.*?继续惰性匹配到下一个双引号,所以整个分组("[^is].*?")就成功匹配到了"This is the tes't"。
如果你的需求是匹配不包含i和s的字符串,那[^is]肯定达不到目的,得用其他写法比如负向预查,但这是另一个话题了。
第二个问题:为什么example.*?(".*?")能匹配,而example(".*?")不行?
核心原因是原字符串中example和目标双引号之间隔了一个左括号(:
- 正则
example(".*?")的逻辑是:找example后面直接跟双引号的内容,但原字符串里example后面是(,不是双引号,自然匹配不到; - 而
example.*?(".*?")里的.*?是惰性匹配任意字符(包括那个左括号(),它会跳过example后面的(,找到后面的双引号,然后完成匹配,所以能成功抓到目标内容。
内容的提问来源于stack exchange,提问作者scott miles
相关产品推荐
相关产品推荐

