有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

html Java正则表达式模式匹配到多个相同标记

问题:

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

背景:

我正在尝试匹配一个字符串<tag TAG1>SOME VALUE</tag TAG1><tag TAG1>ANOTHER VALUE</tag TAG1> 其中TAG1是该特定标记的名称(多个标记可以具有相同的名称,但值不同),而SOME VALUEANOTHER VALUE是标记所包含的不同值

到目前为止,我能够使用regex模式<\\s*tag\\s*.+\\s*>(.*)</\\s*tag\\s*.+\\s*>匹配一对标记,例如<tag TAG1>SOME VALUE</tag TAG1>

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

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


共 (2) 个答案

  1. # 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>
    
  2. # 2 楼答案

    我只是有完全相同的问题,这篇文章帮助了我。我花了一些时间来理解@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生成的基代码