Regexp для поиска фразы, содержащей другую фразу и не помечать ничего другого - PullRequest
0 голосов
/ 18 февраля 2020

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

Пример текстового раздела:

<Text FontFamily="Open Sans" FontSize="19" FontStyle="Normal"
    FontWeight="Normal" HorizontalAlign="Left" Left="803.0"
    Name="Back" Stroke="#CCCCCC" TextDecoration="None"
    Top="126.0" Visibility="Hidden">
... More content here ...
</Text>

Мне нужно найти и удалить только те, которые содержат Name="Back". В других текстовых разделах есть различные атрибуты Name или есть разделы без Name вообще (без имен). Разделы являются многоуровневыми.

Простейшее регулярное выражение:

(?s)<Text (.*?)Name="Back"(.*?)</Text>

и также неправильное. Если появляется Name="Back", то регулярное выражение помечает правильную часть. Но если этой специальной фразы нет, то она начинается с <Text>, затем помечает многие другие текстовые или нет текстовые разделы, пока не найдет </Text>, за которым следует Name="Back", который может находиться в конце файла. Таким образом, он отмечает почти весь файл, много текстов, а не текстовые разделы.

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

Буду благодарен за помощь.

Кстати, как мне избежать < здесь? < плюс Text не будет отображаться в тексте, только в сегменте кода.

1 Ответ

0 голосов
/ 18 февраля 2020

Вы близки, попробуйте это:

(?s)<Text[^>]*? Name="Back".*?>.*?<\/Text>

См. Демонстрацию на https://regex101.com/r/Dmyq59/1

^ Я знаю, что это не Notepad ++, но они оба PCRE


Если вы вставите свое регулярное выражение в мой пример regex101, то это визуализирует для вас проблему, которая является Text (.*?)Name="Back", потому что (.*?) будет продолжать захватывать ВСЕ, пока не достигнет тега, который содержит Name="Back"


Вам настоятельно рекомендуется установить плагин XPatherizerNPP, чтобы вы могли использовать XPath. Эквивалентный XPath был бы //text[@name='Back']

...