【问题标题】:Extracting tags and text between tags using regex使用正则表达式提取标签之间的标签和文本
【发布时间】:2017-02-25 23:34:05
【问题描述】:

我正在尝试使用正则表达式提取 XML 标记和标记中的文本。我知道使用正则表达式不是最好的选择。我的内联文本文件中只有很少的标签,因此没有选择 XML 解析器。

 String txt="American Airlines made <TRIPS> 100 </TRIPS> flights in <DATE> December </DATE> over <ROUTE> Altantic </ROUTE> ";

 String re1="<([^>]+)>"; // Tag 1
 String re2="([^<]*)"; // Variable Name 1
 String re3="</([^>]+)>"; // Tag 2
// String re3 = re1;


    Pattern p = Pattern.compile(re1+re2+re3,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    Matcher m = p.matcher(txt);
    if (m.find())
    {
        String tag1=m.group(1);
        String var1=m.group(2);

        System.out.println(tag1.toString());
        System.out.println(var1.toString());
     }

问题在于,它只识别第一个标签,而不是第二个或后续标签。

电流输出

TRIPS
 100

期望的输出

TRIPS
 100
DATE
 December 
ROUTE
 Altantic

【问题讨论】:

  • 使用&lt;([^&gt;]*)&gt;(.*?)&lt;\/\1&gt; 并提取第二组。
  • if (m.find()) 更改为while (m.find())
  • &lt;TRIPS&gt; 100 &lt;/TRIPS&gt;一样正确关闭TRIPS元素,并使用re3的注释掉版本。否则你将无法匹配正确关闭的其他元素。
  • 我希望你意识到你在做什么。您正在编写一个应用程序,该应用程序仅在以非常特殊的方式编写时才处理 XML。因此,您将成为十几个 SO 问题的原因,这些问题来自人们询问如何使用这种非常特殊的词法形式生成 XML,因为消费应用程序只有在以这种特殊方式编写时才能工作。制定标准是有原因的,这种滥用标准会导致行业中的每个人都产生成本增加。

标签: java regex xml


【解决方案1】:

请将 if 改为 while :

String txt = "American Airlines made <TRIPS> 100 <TRIPS> flights in <DATE> December </DATE> over <ROUTE> Altantic </ROUTE> ";

            String re1 = "<([^>]+)>"; // Tag 1
            String re2 = "([^<]*)"; // Variable Name 1
    // String re3="</([^>]+)>"; // Tag 2
            String re3 = re1;

            Pattern p = Pattern.compile(re1 + re2 + re3, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
            Matcher m = p.matcher(txt);
            while (m.find()) {
                String tag1 = m.group(1);
                String var1 = m.group(2);

                System.out.println(tag1.toString());
                System.out.println(var1.toString());
            }

【讨论】:

    【解决方案2】:

    如果您来到这篇文章是为了寻找一种解析 XML 的方法,请不要阅读这篇文章。请改用 XML 解析器。


    解决方案:

    if (m.find()) 更改为while (m.find())。您可以迭代查找所有匹配项。

    这是查找所有正则表达式匹配的一般情况:

    Pattern p = Pattern.compile(regex,flags);
    Matcher m = p.matcher(text);
    while (m.find())
    {
        System.out.println("First group: " + m.group(1) + 
                           "\nSecond group: " + m.group(2) );
    }
    

    【讨论】: