У меня есть текстовый файл с разными уровнями (структурированный вкладками), и мне нужно выбрать из него определенные значения. Вот пример. Я пробовал это в течение очень долгого времени, но я не могу найти никакого решения.
Connection
Match
Fridolin
Marten
Connection
Inventory
Fill Up
Fill Up
Match
Peter
Marcus
Storage
Room 1
Room 2
Room 3
Match
Albert
Jonas
Hans
List
Match
Peter
Marcus
Я хочу выбрать каждое имя в следующих строках после «Сопоставление» (с одинаковым количеством вкладок перед ним), пока не начнется следующий уровень (разное количество вкладок). В этом случае я хочу выбрать имена, которые перечислены после слова «Совпадение». Пока (например) не появится «Подключение» и не изменится количество вкладок перед ним (уровень). Имена, которые следуют за «Match», всегда находятся на одном уровне. Я не могу использовать многострочный для этого.
Match
Fridolin
Marten
Connection
(?<=Match[\r\n]+\t\t?\t?\t?\t?)([ a-zA-ZäöüÄÖÜßé0-9\.-/\-])+
У меня уже есть это регулярное выражение, которое выбирает по крайней мере первое имя, следующее за «Match». Я не знаю, как выбрать следующие имена и остановиться, если уровень изменится.
@GillesQuénot Только имена. Соединение должно быть конечной точкой.
Вы хотите, чтобы сопоставлялись только имена, которым предшествует Match и которые должны заканчиваться на Connection? и какой язык программирования вы используете?
@SaSkY Да, только те, которым предшествует Match. «Соединение» является переменным и может быть буквально любым. Я просто использую Regex внутри Power Automate Desktop, без определенного языка. Вот почему я не могу использовать многострочный.
@SevenTwo Есть ли максимальное количество имен после Match?
@SaSkY Нет, он должен быть бесконечным, пока вкладки перед ним (уровень) не изменятся в следующей строке (поэтому следующая строка больше не является именем).
Пытаться:
\bMatch\n((\s*).*\n(?:\2.*(?:\n|\Z))*)
Демонстрация регулярных выражений.
Это будет соответствовать Match, следующей за новой строкой, а затем любому количеству пробелов в качестве группы захвата 1. Затем используйте эту группу захвата для сопоставления других строк.
Привет, @Andrej Kesely, спасибо. Но я не могу использовать многострочный, как я написал, и я не хочу выбирать ни вкладки, ни само «Сопоставление». Я действительно хочу выбрать только имена.
Если вы соответствуете остальной части строки, вам не нужно использовать не жадный .*?, вы можете просто сделать это .* regex101.com/r/DBbxpo/1
Привет, @Thefourthbird. У вас есть, может быть, лучшее решение для моей проблемы? Хотя я написал, что это сработало, похоже, это не работает правильно.
@SevenTwo У вас есть 2 ответа, которые решают проблему на текущий вопрос. Если у вас есть другой вопрос, рассмотрите возможность создания нового вопроса.
(?<=Match)\n(\s+)\w+(?:\n\1\w+)+
Онлайн демо
(?<=
оглянитесь, чтобы увидеть, есть ли:
Match
'Соответствовать'
)
конец наблюдения
\n
'\n' (новая строка)
(
сгруппировать и захватить в \1:
\s+
пробел (\n, \r, \t, \f и " ") (1 или более раз (соответствует максимально возможному количеству))
)
конец \1
\w+
символы слова (a-z, A-Z, 0-9, _) (1 или более раз (соответствует максимально возможному количеству))
(?:
сгруппируйте, но не захватывайте (1 или более раз (соответствуя максимально возможному количеству)):
\n
'\n' (новая строка)
\1
что совпало при захвате \1
\w+
символы слова (a-z, A-Z, 0-9, _) (1 или более раз (соответствует максимально возможному количеству))
)+
конец группировкиЭй, @Gilles Quénot, это прекрасно работает. Есть только одна небольшая проблема: как только после совпадения появляется более двух имен, он перестает их выбирать. См., например, третий матч, он пропускает "Ганса". Есть идеи?
Сообщение отредактировано соответственно
Это работает для конкретного примера, где есть только два имени после каждого совпадения, и они имеют отступ с одинаковым количеством пробелов. Однако, если имен больше или отступ другой, это регулярное выражение не будет соответствовать всем именам. Этот подойдет лучше:(?<=Match\r?\n)(?:\t+[^\t\r\n]+\r?\n)+
Привет @Kylar, твой подход похож на мой. Проблема в том, что это просто выбирает ВСЕ после матча. Я действительно хочу выбирать имена только после того, где используется совпадение, пока вкладки перед ним не изменятся в следующей строке (поэтому следующая строка больше не является именем).
@SevenTwo Понятно, в этом случае вы можете искать строки, которые начинаются с того же количества вкладок, что и строка «Сопоставление», но перестают соответствовать, как только будет найдена строка с меньшим количеством вкладок. (?<=Match\r?\n)((?:\t+[^\t\r\n]+\r?\n)+(?!\t)) Как это?
@Kylar Спасибо за ваши усилия! К сожалению, это делает то же самое. Единственное, что он начинается на более позднем "Матч"
@Gilles Quénot С небольшим редактированием это сработало. Спасибо!
Вам действительно не нужен внешний вид, вы также можете сопоставить его :-)
Вы хотите получить только имена или также Connection?