. net regex - строки, не содержащие полной остановки в последнем элементе списка - PullRequest
0 голосов
/ 21 января 2020

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

В конце каждой строки в данных есть разрывы строк и возврат каретки.

Схема используется для XML.

Пример хорошего XML Данные:

<randlist prefix="unorder">
    <item>abc</item>
    <item>abc</item>
    <item>abc.</item>
</randlist>

Пример плохого XML Данные - регулярное выражение должно дать совпадения - нет полной остановки перед последним </item>:

<randlist prefix="unorder">
    <item>abc</item>
    <item>abc</item>
    <item>abc</item>
</randlist>

Шаблон регулярного выражения Я пробовал, что не работало с плохими данными XML (не проверено на хороших данных XML):

^<randlist \w*=[\S\s]*\.*[^.]<\/item>[\n]*<\/randlist>$

Результаты с использованием http://regexstorm.net/tester:

0 matches

Результаты с использованием https://regex101.com/:

0 matches

This вопрос отличается от следующего imo, из-за полного останова и начала строковых критериев:

регулярное выражение для строки, не заканчивающейся данным суффиксом

Пояснение от 3 :

/
^<randlist \w*=[\S\s]*\.*[^.]<\/item>[\n]*<\/randlist>$
/
gm
^ asserts position at start of a line
<randlist  matches the characters <randlist  literally (case sensitive)
\w* matches any word character (equal to [a-zA-Z0-9_])
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
= matches the character = literally (case sensitive)
Match a single character present in the list below [\S\s]*
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\S matches any non-whitespace character (equal to [^\r\n\t\f\v ])
\s matches any whitespace character (equal to [\r\n\t\f\v ])
\.* matches the character . literally (case sensitive)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
Match a single character not present in the list below [^.]
. matches the character . literally (case sensitive)
< matches the character < literally (case sensitive)
\/ matches the character / literally (case sensitive)
item> matches the characters item> literally (case sensitive)
Match a single character present in the list below [\n]*
< matches the character < literally (case sensitive)
\/ matches the character / literally (case sensitive)
randlist> matches the characters randlist> literally (case sensitive)
$ asserts position at the end of a line
Global pattern flags
g modifier: global. All matches (don't return after first match)
m modifier: multi line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)

1 Ответ

0 голосов
/ 21 января 2020

@ Сильванас абсолютно прав. Вы не должны использовать Regex для этой проблемы, вы должны использовать некоторую форму синтаксического анализатора XML для чтения данных и поиска строк с .. Однако, если по какой-то ужасной причине вы ДОЛЖНЫ использовать Regex, и если ваши данные структурированы точно так же, как ваш пример, то решение Regex будет следующим:

^\s+<item>[^<]*?(?<=\.)<\/item>$

Если есть ARE совпадений с этим регулярным выражением, ваш xml искажен . Но опять же, это регулярное выражение завершается ошибкой, если пробел не верен, если в строке есть что-то еще, если теги не <item>..</item>, и так далее, и так далее. Опять же, вам было бы гораздо лучше не использовать Regex для этой проблемы, если вы не можете абсолютно гарантировать , что все, кроме . будет хорошо сформировано XML

РЕДАКТИРОВАТЬ: Если открывающий и закрывающий тег находятся на одной строке, но они не обязательно называются «item» и могут иметь атрибуты, на go вперед и попробуйте следующее:

^\s+<([^<>\s]+)[^<>]*>[^<>]*?(?<=\.)<\/\1>$

Breakdown:
^           anchor to beginning of line
\s+         skip over any whitespace
<           found what looks like an opening tag
([^[]\s]+)  match the first word found after the "<", store in capture group 1
[^<>]*>     match whatever remain until the closing ">"
[^<>]*?     match all of the contents up until the next "<"
(?<=\.)     ensure the last character was a "."
<\/\1>      match a closing tag where the text after the / is the same as the first word of the opening tag (stored in capture group 1)
$           anchor to end of line

Убедитесь, что у вас установлена ​​опция MultiLine regex, иначе ^ и $ будут соответствовать началу / концу всей строки. Как и прежде, любые совпадения с этим регулярным выражением означают, что XML плохо сформирован в этой строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...