Regex для поиска именованных тегов XML, которые могут быть пустыми - PullRequest
1 голос
/ 25 марта 2019

У меня проблема с поиском определенных именованных тегов xml в текстовом блоке, который может быть или не быть пустым.Я не уверен, что проблема все-таки решается с помощью регулярных выражений.

Например, у меня есть следующий текстовый блок:

...<item name="xxx">yyyy</item>....

Чтобы отфильтровать тег 'item' с его атрибутами Ia используйте следующее регулярное выражение:

<item(.*?)>(.*?)</item>|<item(.*?)./>

Это регулярное выражение также работает с пустыми тегами, как в следующем примере текста:

...<item name="zzz" />....

Моя проблема состоит в том, что мой текст содержит несколько тегов 'item',Это работает до тех пор, пока я не смешиваю пустые и непустые теги, как в следующем примере текстового блока:

...<item name="zzz" />....
...<item name="xxx">yyyy</item>....

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

<item name="zzz" />.......<item name="xxx">yyyy</item>

Мой вопрос: эта проблема разрешима с помощью регулярных выражений?Первым делом я использовал такую ​​комбинацию «И НЕ», как

(<item(.*?))(?!/>)>(.*?)</item>

Но я не смог решить эту проблему.

Мой код Java для применения регулярного выражения к заданному текстовому блоку выглядит следующим образом:

Pattern pattern = Pattern.compile("<item(.*?)>(.*?)</item>|<item(.*?)./>", Pattern.DOTALL);
Matcher matcher = pattern.matcher(textblock);
while (matcher.find()) {
   String attributes = matcher.group(1);
   ....
}

1 Ответ

1 голос
/ 25 марта 2019

Ваше регулярное выражение будет работать, если с помощью атрибутов тега regex, определенных в w3c
, вы можете получить 100% точность при поиске открытых и автономных тегов.

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

Raw:

(?s)(?:(<item(?>\b(?:".*?"|'.*?'|[^>]*?)*>)(?<=/>))|(<item(?>\b(?:".*?"|'.*?'|[^>]*?)*>)(?<!/>))(.*?)(</item\s*>))

Двойные кавычки:

"(?s)(?:(<item(?>\\b(?:\".*?\"|'.*?'|[^>]*?)*>)(?<=/>))|(<item(?>\\b(?:\".*?\"|'.*?'|[^>]*?)*>)(?<!/>))(.*?)(</item\\s*>))"

https://regex101.com/r/R3iVVW/1

 (?s)
 (?:
      (                                    # (1 start), Self Contained item
           <item
           (?>                                  # Atomic to trap self contained
                \b  
                (?: " .*? " | ' .*? ' | [^>]*? )*
                > 
           )
           (?<= /> )                            # Must be a self contained item

      )                                    # (1 end)

   |                                     # OR, 

      (                                    # (2 start), Open item
           <item
           (?>                                  # Atomic to trap self contained
                \b 
                (?: " .*? " | ' .*? ' | [^>]*? )*
                >
           )
           (?<! /> )                            # Not a self contained item
      )                                    # (2 end)
      ( .*? )                              # (3), Item content
      ( </item \s* > )                     # (4), Close item
 )

Сравнительный анализ:

Regex1:   (?s)(?:(<item(?>\b(?:".*?"|'.*?'|[^>]*?)*>)(?<=/>))|(<item(?>\b(?:".*?"|'.*?'|[^>]*?)*>)(?<!/>))(.*?)(</item\s*>))
Options:  < none >
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   14
Elapsed Time:    4.73 s,   4728.21 ms,   4728214 µs
Matches per sec:   148,047
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...