Matcher在正则表达式模式上返回匹配,但split()无法在同一个正则表达式上找到匹配项?

时间:2010-01-31 02:09:22

标签: java regex

我看不出匹配器会在模式上返回匹配的原因,但split会在同一个正则表达式模式上返回零长度数组。它应该返回一些东西 - 在这个例子中,我正在寻找包含“param / value”的2个单独字符串的返回。

public class MyClass {

    protected Pattern regEx = "(([a-z])+/{1}([a-z0-9])+/?)*";

    public void someMethod() {
        String qs = "param/value/param/value";
        Matcher matcherParamsRegEx = this.regEx.matcher(qs);
        if (matcherParamsRegEx.matches()) { // This finds a match.
            String[] parameterValues = qs.split(this.regEx.pattern()); // No matches... zero length array.
        }
    }
}

3 个答案:

答案 0 :(得分:4)

模式可以匹配整个字符串。 split()不会返回匹配项,只会返回其中的匹配项。由于模式匹配整个字符串,只返回一个空字符串。我认为你可能对split()所做的事情存在误解。

例如:

String qs = "param/value/param/value";
String pieces = qs.split("/"); 

将返回一个包含4个元素的数组:param,value,param,value。

请注意,您不会返回搜索的内容(“/”)。

你的正则表达式有些过于复杂。首先,你使用的是{1},这是不必要的。其次,当你执行([a-z])+时,你将只捕获一个后者(最后一个遇到。将其与([a-z]+)进行比较,这将捕获整个匹配。此外,你甚至不需要为此捕获。模式可以简化为:

protected Pattern regEx = Pattern.compile("[a-z]+/([a-z0-9]+/?)*");

从技术上讲:

protected Pattern regEx = "(([a-z])+/{1}([a-z0-9])+/?)*";

是编译器错误,因此您实际运行的内容与您发布的内容可能是任何内容。

答案 1 :(得分:2)

这里的问题是split拆分围绕匹配正则表达式。你有两个连续的匹配,其间没有别的,所以split没有任何东西可以返回。

我看不到任何方法可以使用split从该字符串中获取您想要的内容,但如果您可以使用不同的分隔符来分隔对,而不是使用单独的名称和值,这将有助于很多。

否则,您可能会拆分斜杠并将交替结果作为名称和值,但这很容易出错。

答案 2 :(得分:2)

正则表达式匹配 - 如果不匹配,你将获得一个单元素数组,该元素是整个原始字符串。你对split()的工作方式有错误的想法。在第一次匹配尝试时,它找到“param / value /”并将该匹配之前的所有内容存储为第一个标记:空字符串。第二次尝试找到“param / value”并存储它与第一个匹配之间的任何内容作为下一个标记:另一个空字符串。第三次匹配尝试失败,因此第二次匹配和字符串结尾之间的任何内容都成为最终标记:还有另一个空字符串。

存储了所有令牌后,split()反向遍历它们,检查尾随的空令牌。第三个标记确实是空的,因此删除了那个标记。第二个也是空的,所以删除那一个。你看到这是怎么回事?你可以强制split()通过传递一个负整数作为第二个参数来保留尾随的空匹配,但这显然对你没有任何帮助。您需要根据正则表达式包的实际工作方式重新考虑您的问题(无论它是什么)。