Неожиданный матч с регулярным выражением Java

Я хочу найти теги XML типа X в тексте, который

  • пусты (содержит только пробелы)
  • может иметь или не иметь атрибуты

Тоже как то так

<x>  </x>
<x a="v">  </x>

Я использую следующее регулярное выражение в сочетании с функцией поиска Matcher.

<x.*?> +</x>

Я получаю матчи, которые не ожидаю. Смотрите следующий тест

@Test
public void sample() throws Exception
{
    String text = "Lorem <x>ipsum <x>dolor sit amet</x> </x>";
    String regex = "<x.*?> +</x>";

    Matcher matcher = Pattern.compile(regex).matcher(text);
    assertFalse(matcher.find());
}

Тест не пройден. Вместо этого это правда

assertTrue(matcher.find());
assertEquals("<x>ipsum <x>dolor sit amet</x> </x>", matcher.group());

Функция find не поддерживает не жадный оператор или что здесь не так?

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

1 ответ

Решение

.*? квантификатор означает, что он найдет как можно меньше символов, чтобы удовлетворить соответствие, это не значит, что он остановит поиск при первом > это находит. Так что в вашем примере <x.*?> будет соответствовать всем:

<x>ipsum <x>dolor sit amet</x>

Со всеми персонажами между первым x и финал > удовлетворяя .*?, Чтобы это исправить, вы можете просто изменить свой шаблон на:

<x[^>]*> +</x>

Кстати, об этом уже говорилось много раз, но вы не должны использовать регулярные выражения для разбора xml / html / xhtml.

Другие вопросы по тегам