Подтвердить что ты не робот

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

Не уверен, что делать дальше. Есть идеи? Спасибо.

4b9b3361

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

Ответ 2

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

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

Если вы разбираете XML файлы, вы должны использовать библиотеку 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));
        }
    }

Ответ 4

    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

Попробуйте следующее:

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%

Ответ 6

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

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

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

Ответ 7

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