Java регулярное выражение для извлечения текста между тегами - PullRequest
72 голосов
/ 03 июля 2011

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

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

158 голосов
/ 03 июля 2011

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

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

10 голосов
/ 03 июля 2011

Честно говоря, регулярные выражения - не лучшая идея для этого типа анализа.Публикуемое вами регулярное выражение, вероятно, отлично подойдет для простых случаев, но если все усложнится, у вас будут огромные проблемы (по той же причине, по которой вы не можете надежно анализировать HTML с помощью регулярных выражений).Я знаю, что вы, вероятно, не хотите этого слышать, я знаю, что не сделал этого, когда я задал тот же тип вопросов, но разбор строк стал НАМ ПРАВИЛЬНО более надежным после того, как я перестал пытаться использовать регулярные выражения для всего.

jTopas - это токенизатор AWESOME, который позволяет довольно легко писать парсеры вручную (я НАСТОЯТЕЛЬНО рекомендую jtopas по сравнению со стандартными библиотеками java scanner / etc ..).Если вы хотите увидеть jtopas в действии, здесь - это некоторые парсеры, которые я написал, используя jTopas для анализа этого типа файла

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

6 голосов
/ 03 сентября 2015

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

    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));
        }
    }
2 голосов
/ 23 октября 2015

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

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%

2 голосов
/ 04 декабря 2013
    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));
1 голос
/ 03 июля 2011

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

При этом вам нужно продолжить, сопоставив строку и выбрав нужную группу:

if (m.matches())
{
   String result = m.group(1);
   // do something with result
}
0 голосов
/ 24 июля 2017
    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++;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...