Java正则表达式提取标签之间的文本

Posted

技术标签:

【中文标题】Java正则表达式提取标签之间的文本【英文标题】:Java regex to extract text between tags 【发布时间】:2011-09-27 11:43:55 【问题描述】:

我有一个包含一些自定义标签的文件,我想编写一个正则表达式来提取标签之间的字符串。例如,如果我的标签是:

[customtag]String I want to extract[/customtag]

我将如何编写一个正则表达式来仅提取标签之间的字符串。这段代码似乎是朝着正确方向迈出的一步:

Pattern p = Pattern.compile("[customtag](.+?)[/customtag]");
Matcher m = p.matcher("[customtag]String I want to extract[/customtag]");

不知道下一步该做什么。有任何想法吗?谢谢。

【问题讨论】:

对于初学者,您需要转义 [] 方括号,它们是正则表达式中的元字符。 【参考方案1】:

你在正确的轨道上。现在你只需要提取所需的组,如下:

final Pattern pattern = Pattern.compile("<tag>(.+?)</tag>", Pattern.DOTALL);
final Matcher matcher = pattern.matcher("<tag>String I want to extract</tag>");
matcher.find();
System.out.println(matcher.group(1)); // Prints String I want to extract

如果你想提取多个匹配,试试这个:

public static void main(String[] args) 
    final String str = "<tag>apple</tag><b>hello</b><tag>orange</tag><tag>pear</tag>";
    System.out.println(Arrays.toString(getTagValues(str).toArray())); // Prints [apple, orange, pear]


private static final Pattern TAG_REGEX = Pattern.compile("<tag>(.+?)</tag>", Pattern.DOTALL);

private static List<String> getTagValues(final String str) 
    final List<String> tagValues = new ArrayList<String>();
    final Matcher matcher = TAG_REGEX.matcher(str);
    while (matcher.find()) 
        tagValues.add(matcher.group(1));
    
    return tagValues;

但是,我同意正则表达式不是这里的最佳答案。我会使用 XPath 来查找我感兴趣的元素。有关详细信息,请参阅 The Java XPath API。

【讨论】:

非常感谢,这正是我所需要的。我将研究 XPaths,但现在我认为这个解决方案会起作用。我的应用程序非常简单,并且可能会保持这种状态。再次感谢! 这个字符串"&lt;tag&gt;apple&lt;/tag&gt;&lt;b&gt;hello&lt;/b&gt;&lt;tag&gt;orange&lt;/tag&gt;&lt;tag&gt;pear"怎么样?我们如何在没有关闭标签的情况下获得pear 概括:private String extractDataFromTags(String tag) Pattern pattern = Pattern.compile("<.>(.+?)+?>");匹配器 matcher = pattern.matcher(tag); matcher.find();返回(matcher.group(1)); // 打印我要提取的字符串或抛出异常 【参考方案2】:

说实话,正则表达式并不是这种解析的最佳方法。您发布的正则表达式可能适用于简单的情况,但如果事情变得更复杂,您将遇到巨大的问题(与您无法使用正则表达式可靠地解析 html 的原因相同)。我知道你可能不想听到这个,我知道当我问相同类型的问题时我不想听到,但是在我停止尝试对所有内容使用正则表达式后,字符串解析对我来说变得更加可靠。

jTopas 是一个很棒的分词器,可以很容易地手动编写解析器(我强烈建议使用 jtopas,而不是标准的 java 扫描器/etc.. 库)。如果您想查看 jtopas 的运行情况,here 是我使用 jTopas 编写的一些解析器来解析 this 类型的文件

如果您正在解析 XML 文件,您应该使用 xml 解析器库。除非您只是为了好玩,否则不要自己做,那里有很多经过验证的选择

【讨论】:

感谢您的建议。我已经为它们添加了书签,我肯定会考虑在未来的项目中使用它。现在正则表达式方法可能是我要使用的方法,因为我正在解析的文件非常小/简单。【参考方案3】:

一种查找标签、属性和值的通用、更简单且有点原始的方法

    Pattern pattern = Pattern.compile("<(\\w+)( +.+)*>((.*))</\\1>");
    System.out.println(pattern.matcher("<asd> TEST</asd>").find());
    System.out.println(pattern.matcher("<asd TEST</asd>").find());
    System.out.println(pattern.matcher("<asd attr='3'> TEST</asd>").find());
    System.out.println(pattern.matcher("<asd> <x>TEST<x>asd>").find());
    System.out.println("-------");
    Matcher matcher = pattern.matcher("<as x> TEST</as>");
    if (matcher.find()) 
        for (int i = 0; i <= matcher.groupCount(); i++) 
            System.out.println(i + ":" + matcher.group(i));
        
    

【讨论】:

如果有一系列不同的标签或嵌套标签,如&lt;h2&gt;Mac&lt;/h2&gt;&lt;h1&gt;loves it&lt;/h1&gt;&lt;h2&gt;Mac&lt;h1&gt;liked your answer&lt;/h1&gt;&lt;/h2&gt;,模式会是什么? 请编辑 i 【参考方案4】:

试试这个:

Pattern p = Pattern.compile(?<=\\<(any_tag)\\>)(\\s*.*\\s*)(?=\\<\\/(any_tag)\\>);
Matcher m = p.matcher(anyString);

例如:

String str = "<TR> <TD>1Q Ene</TD> <TD>3.08%</TD> </TR>";
Pattern p = Pattern.compile("(?<=\\<TD\\>)(\\s*.*\\s*)(?=\\<\\/TD\\>)");
Matcher m = p.matcher(str);
while(m.find())
   Log.e("Regex"," Regex result: " + m.group())       

输出:

10 恩

3.08%

【讨论】:

【参考方案5】:
    String s = "<B><G>Test</G></B><C>Test1</C>";

    String pattern ="\\<(.+)\\>([^\\<\\>]+)\\<\\/\\1\\>";

       int count = 0;

        Pattern p = Pattern.compile(pattern);
        Matcher m =  p.matcher(s);
        while(m.find())
        
            System.out.println(m.group(2));
            count++;
        

【讨论】:

【参考方案6】:
    final Pattern pattern = Pattern.compile("tag\\](.+?)\\[/tag");
    final Matcher matcher = pattern.matcher("[tag]String I want to extract[/tag]");
    matcher.find();
    System.out.println(matcher.group(1));

【讨论】:

标签的前缀怎么样(如果前缀是动态的)【参考方案7】:

我在这个回复前加上“你不应该使用正则表达式来解析 XML ——它只会导致无法正常工作的边缘情况,以及在你尝试的时候永远增加复杂性的正则表达式修复它。”

话虽如此,您需要继续匹配字符串并获取所需的组:

if (m.matches())

   String result = m.group(1);
   // do something with result

【讨论】:

以上是关于Java正则表达式提取标签之间的文本的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式提取方括号之间的文本[重复]

正则表达式提取方括号或大括号之间的文本

实例JS 正则表达式提取 html 中纯文本,去掉样式,其它标签

实例JS 正则表达式提取 html 中纯文本,去掉样式,其它标签

实例JS 正则表达式提取 html 中纯文本,去掉样式,其它标签

实例JS 正则表达式提取 html 中纯文本,去掉样式,其它标签