20

我有以下 Java 代码:

Pattern pat = Pattern.compile("(?<!function )\\w+");
Matcher mat = pat.matcher("function example");
System.out.println(mat.find());

为什么mat.find()返回true?我使用了否定的lookbehind,并example在前面加上function. 不应该丢弃吗?

4

3 回答 3

36

看看它匹配什么:

public static void main(String[] args) throws Exception {
    Pattern pat = Pattern.compile("(?<!function )\\w+");
    Matcher mat = pat.matcher("function example");
    while (mat.find()) {
        System.out.println(mat.group());
    }
}

输出:

function
xample

所以首先它会找到function前面没有“ function”的 。然后它会发现xample哪个在前面function e,因此不是“ function”。

大概你希望模式匹配整个文本,而不仅仅是文本中查找匹配项。

你可以这样做Matcher.matches()也可以更改模式以添加开始和结束锚点:

^(?<!function )\\w+$

我更喜欢第二种方法,因为这意味着模式本身定义了它的匹配区域,而不是由它的用法定义的区域。然而,这只是一个偏好问题。

于 2013-08-02T11:32:15.047 回答
1

您的字符串包含匹配 \w+ 的单词“function”,并且前面没有“function”。

于 2013-08-02T11:32:10.150 回答
1

这里注意两点:

  • 您正在使用which为子字符串匹配find()返回true 。

  • 由于上述原因,“function”匹配,因为它前面没有“function”。
    整个字符串永远不会匹配,因为您的正则表达式不包含空格。

使用Mathcher#matches()or^$带有负前瞻的锚点:

Pattern pat = Pattern.compile("^(?!function)[\\w\\s]+$"); // added \s for whitespaces
Matcher mat = pat.matcher("function example");

System.out.println(mat.find()); // false
于 2013-08-02T11:33:07.643 回答