Регулярное выражение Java для извлечения текста между тегами


у меня есть файл с некоторыми пользовательскими тегами, и я хотел бы написать регулярное выражение для извлечения строки между тегами. Например, если мой тег:

[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 66

7 ответов:

вы на правильном пути. Теперь вам просто нужно извлечь нужную группу, следующим образом:

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

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, чтобы найти элементы, которые меня интересуют. Смотрите JAVA XPath API для получения дополнительной информации.

честно говоря, регулярные выражения не лучшая идея для этого типа анализа. Регулярное выражение, которое вы опубликовали, вероятно, будет отлично работать для простых случаев, но если все станет сложнее, у вас будут огромные проблемы (по той же причине, почему вы не можете надежно анализировать HTML с регулярными выражениями). Я знаю, что вы, вероятно, не хотите этого слышать, Я знаю, что не задавал таких же вопросов, но разбор строк стал более надежным для меня после того, как я перестал пытаться использовать регулярные выражения для всего.

jTopas это удивительный токенизатор, который позволяет довольно легко писать Парсеры вручную (я настоятельно рекомендую jtopas над стандартным сканером java/etc.. библиотеки.) Если вы хотите увидеть jtopas в действии, здесь некоторые Парсеры я написал с помощью jTopas для разбора этой тип файла

если вы анализируете XML-файлы, вы должны использовать библиотеку синтаксического анализа xml. Не делайте этого сами, если вы не являетесь просто делаю это для удовольствия, есть много проверенных вариантов там

общий, более простой и немного примитивный подход к поиску тега, атрибута и значения

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

попробуйте это:

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%

Я префикс этого ответа: "вы не должны использовать регулярное выражение для анализа XML-это приведет только к краевым случаям, которые не работают правильно, и постоянно увеличивающемуся в сложности регулярному выражению, пока вы пытаетесь его исправить."

как говорится, вам нужно продолжить, сопоставив строку и захватив нужную группу:

if (m.matches())
{
   String result = m.group(1);
   // do something with result
}
    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++;
        }