Java正则表达式在标记之间提取文本

时间:2011-07-03 02:01:55

标签: java regex

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

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

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

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

不确定下一步该怎么做。有任何想法吗?感谢。

7 个答案:

答案 0 :(得分:153)

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

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

答案 1 :(得分:10)

说实话,正则表达式不是这种解析的最佳选择。你发布的正则表达式可能适用于简单的情况,但如果事情变得更复杂,你将会遇到很大的问题(同样的原因,你不能用正则表达式可靠地解析HTML)。我知道你可能不想听到这个,我知道当我问同样类型的问题时我没有,但在我停止尝试使用正则表达式之后,字符串解析变得更加可靠。

jTopas是一个非常好的标记器,可以很容易地手动编写解析器(我强烈建议使用标准java扫描程序/等等的jtopas库)。如果你想看到jtopas在运行,here是我用jTopas编写的一些解析器来解析this类型的文件

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

答案 2 :(得分:6)

查找标记,属性和值的通用,更简单和有点原始的方法

    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));
        }
    }

答案 3 :(得分:3)

试试这个:

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 Ene

3.08%

答案 4 :(得分:2)

    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));

答案 5 :(得分:1)

我在此回复前加上“您不应该使用正则表达式来解析XML - 它只会导致边缘情况无法正常工作,并且会导致复杂性永远增加的正则表达式解决它。“

话虽这么说,你需要通过匹配字符串并抓住你想要的组来继续:

if (m.matches())
{
   String result = m.group(1);
   // do something with result
}

答案 6 :(得分:0)

    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++;
        }