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]");
Не уверен, что делать дальше. Есть идеи? Спасибо.
Ответы
Ответ 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++;
}