Java正则表达式模式匹配多个相同的标签

时间:2016-05-26 14:27:32

标签: java html regex xml

问题:

如何将<tag TAG1>SOME VALUE</tag TAG1><tag TAG1>ANOTHER VALUE</tag TAG1>成功匹配为2个单独的值?

背景

我正在尝试匹配字符串<tag TAG1>SOME VALUE</tag TAG1><tag TAG1>ANOTHER VALUE</tag TAG1> 如果TAG1是该特定代码的名称(多个代码可以具有相同的名称但值不同),SOME VALUEANOTHER VALUE是由代码包含的不同值。

到目前为止,我可以使用正则表达式<tag TAG1>SOME VALUE</tag TAG1>匹配一对标签<\\s*tag\\s*.+\\s*>(.*)</\\s*tag\\s*.+\\s*>

上面的示例是最糟糕的情况,没有字符分隔第一个标记的结尾和第二个标记的开头。我的问题是,当我使用我的正则表达式字符串运行find()时,我得到两个标记,好像它们是一个标记。

问题在于标记(.*)之间的通配符,因为它不排除标记的结束/开始。我需要通配符匹配,因为任何字符(包括\n)都可以在标记内。我还使用Pattern.DOTALL成功地将1个标记与其中的换行符匹配。

2 个答案:

答案 0 :(得分:1)

以下是如何做到这一点:

String value = "<tag TAG1>SOME VALUE</tag TAG1><tag TAG1>ANOTHER VALUE</tag TAG1>";
Pattern pattern = Pattern.compile("<\\s*tag\\s*[^>]+\\s*>([^(</)]*)</\\s*tag\\s*[^>]+\\s*>");
Matcher matcher = pattern.matcher(value);
while (matcher.find()) {
    System.out.println(matcher.group());
}

<强>输出:

<tag TAG1>SOME VALUE</tag TAG1>
<tag TAG1>ANOTHER VALUE</tag TAG1>

答案 1 :(得分:0)

我只是遇到了完全相同的问题,这篇文章帮助了我。我花了一些时间来了解@Nicolas Filotto在他的正则表达式中做了什么,如果您相信所有标签的格式,它都可以变得更简单。

回答原始问题如何停止通配符匹配所有内容就是宁愿对您不想要的内容进行反向匹配。寻找除标记结尾之外的任何字符。

模式(不使用字符串转义符):<tag TAG1>([^(<\/)]*)<\/tag TAG1>

import java.util.regex.Matcher;
import java.util.regex.Pattern;

String regex = "<tag TAG1>([^(<\\/)]*)<\\/tag TAG1>";
String string = "<tag TAG1>SOME VALUE</tag TAG1><tag TAG1>ANOTHER VALUE</tag TAG1><tag TAG1>ANOTHER VALUE WITH \nNEWLINE</tag TAG1>";

Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    println("Full match: " + matcher.group(0));
    for (int i = 1; i <= matcher.groupCount(); i++) {
        println("Group " + i + ": " + matcher.group(i));
    }
}

https://regex101.com生成的基本代码