正则表达式匹配多种模式

时间:2014-07-15 20:35:15

标签: java regex

我正在尝试编译一个Java Regex模式,但是该模式会查找3个不同的匹配项。我已经知道我可以使用管道(|)来做到这一点,但是我对正则表达式的实际语法有困难。

我正在浏览XML数据并尝试取出3场比赛。 XML看起来像这样:

<Element createdOn="1405358703367" updatedOn="1405358718804" url="http://www.someurl.com" />

我正在尝试的正则表达式到目前为止看起来像这样:

((?<="url": ").*(?=")) | (createdOn="(\d)") | (updatedOn="(\d)")

最后,我需要获取XML中引号之间的所有内容(即14053587033671405358718804http://www.someurl.com

我之前有自己的URL正则表达式,但似乎没有匹配。

感谢。

3 个答案:

答案 0 :(得分:1)

从索引2获取匹配的组。

(url|createdOn|updatedOn)="([^"]*)"

DEMO

以下是示例代码:

String string = "<Element createdOn=\"1405358703367\" updatedOn=\"1405358718804\" url=\"http://www.someurl.com\" />";
String patternString = "(url|createdOn|updatedOn)=\"([^\"]*)\"";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println(matcher.group(2));
}

输出:

1405358703367
1405358718804
http://www.someurl.com

答案 1 :(得分:0)

Java没有提取匹配项的库方法,但您只需要一行:

String[] matches = input.replaceAll("^[^\"]*\"|\"[^\"]*$", "").split("\"[^\"]*\"");

这可以通过从第一个/最后一个引号中删除前导和尾随输入,然后在quote-nonquo​​te-quote输入上拆分,将目标匹配保留为数组。


行动中:

String input = "<Element createdOn=\"1405358703367\" updatedOn=\"1405358718804\" url=\"http://www.someurl.com\" />";
String[] matches = input.replaceAll("^[^\"]*\"|\"[^\"]*$", "").split("\"[^\"]*\"");
System.out.println(Arrays.toString(matches));

输出:

[1405358703367, 1405358718804, http://www.someurl.com]

答案 2 :(得分:0)

管道(|)用于查找可能 some-pattern some-other-pattern 的匹配项另一个图案。它不擅长发现所有出现的几种模式。要做到这一点,如果您要查找的模式不一定是固定顺序,那么您需要使用循环。

这是一个代码示例,以您尝试的模式开头,修复了一些问题,并使用循环查找模式:

    Pattern p = Pattern.compile("((?<=url=\").*(?=\"))|(createdOn=\"(\\d+)\")|(updatedOn=\"(\\d+)\")");
    Matcher m = p.matcher(source);
    while (m.find()) {
        System.out.println("Found: "+m.group());
        System.out.println("Group 1: "+m.group(1));
        System.out.println("Group 3: "+m.group(3));
        System.out.println("Group 5: "+m.group(5));
    }

(原始模式的一些问题:你在每个|之前和之后放置了空格字符,这些字符按字面处理并且意味着模式必须匹配那些不存在的空格。我添加了{{1在+之后,因为你想要匹配多个数字。有一些错误,例如在\\d而不是:后放url。)

现在代码使用循环来查找与您正在查找的模式之一匹配的每个连续模式。它匹配=url=...createdOn=...,但通过使用循环,我们将找到所有这些。 (请注意,如果它在源代码中看到updatedOn=...url属性两次,则无关心。您必须自己检查一下。)

没有参数的createdOn方法将返回模式匹配的任何内容。 group()group(1)group(3)会返回该模式的某些子部分;数字是通过计算除group(5)之外的模式中(的使用位置来确定的。因此,组1使用(?作为后视匹配的东西;第2组以url开头;第3组是createdOn之后的数字序列;第4组以createdOn等开头。设置模式的方式,并非所有模式都有值,因为updatedOn分隔的三个选项中只有一个匹配。其余的将是|。因此,上述代码的输出将为两个组显示null,为另一个组显示有用的值。如果您以这种方式执行操作,则需要测试null以查看实际返回的值。

这也是命名捕获组可能有用的情况。见http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.htmlnull有一个Matcher函数,它将组名作为参数。

这是一种方法,但是字符串解析总是有多种方法,这里发布的其他答案也是有效的。此外,已经有XML解析器可以为您处理这类事情。

注意:这个答案是为了指出group(name)的工作原理。我并不建议以这种方式做事,因为它过于复杂。如果您要分别查看每个属性,那么设置三个模式并一次查找每个模式会更简单。或者在循环中使用@ braj的建议,然后执行稍后的检查以确保|createdOn值是数字。