#regex #powershell #parsing #text #split
#регулярное выражение #powershell #синтаксический анализ #текст #разделить
Вопрос:
У меня есть блок текста, который мне нужно проанализировать (сохраненный в переменной), но я не уверен, как это сделать. Этот блок текста, сохраненный в переменной, которую мы можем вызвать $block
для простоты, включает все пробелы, показанные ниже.
Я бы хотел, чтобы результатом был список с возможностью повторения, первым значением которого является Health_AEPOEP_Membership_Summary - Dev
, а вторым — Health_AEPOEP_YoY_Comparison_Summary - Dev
. Предположим, что этот список книг может быть длиннее (до 50) или короче (минимум 1 книга), и все книги отформатированы одинаково (в терминах name_with_underscores - Dev
. Я бы попробовал этот $block.split(" ")
метод, но этот метод дает много пробелов, которые может быть трудно перечислить и учесть.
Workbooks : Health_AEPOEP_Membership_Summary - Dev [Project: Health - Dev]
Health_AEPOEP_YoY_Comparison_Summary - Dev [Project: Health - Dev]
Любая помощь очень ценится!
Комментарии:
1. Вы узнаете все, что вам нужно, когда посмотрите это видео: сложные методы синтаксического анализа обычного текста
Ответ №1:
Вы могли бы написать многострочный шаблон регулярных выражений и попытаться извлечь имена, но, возможно, было бы проще рассуждать, если вы просто разбили его на простые (r) шаги:
$string = @'
Workbooks : Health_AEPOEP_Membership_Summary - Dev [Project: Health - Dev]
Health_AEPOEP_YoY_Comparison_Summary - Dev [Project: Health - Dev]
'@
# Split into one string per line
$strings = $string -split 'r?n'
# Remove leading whitespace
$strings = $strings -replace '^s*'
# Remove `Workbooks : ` prefix (strings that don't match will be left untouched)
$strings = $strings -replace '^Workbooks :s*'
# Remove `[Project $NAME]` suffix
$strings = $strings -replace 's*[Project: [^]] ]'
# Get rid of empty lines
$strings = $strings |Where-Object Length
$strings
теперь содержит два имени проекта
Комментарии:
1. И я слышал, что SO не должен быть бесплатным сервисом для написания кода. 😉
2. когда я запускаю это,
[Project...]
текст остается. Почему это так?3. @AmeeraKhan В шаблоне регулярных выражений была опечатка (я забыл экранировать
[
), я обновил ее сейчас
Ответ №2:
Если текст находится в файле, это немного упростит задачу, и я бы рекомендовал этот подход
switch -Regex -file ($file){
'(w _. - Dev)' {$matches.1}
}
Подробности регулярного выражения
()
— группа захвата
w
— сопоставить один или несколько буквенных символов
_
— сопоставление буквенного подчеркивания
.
— сопоставьте один или несколько любых символов
- Dev
— буквальное совпадение с тире.
Если это уже в переменной, это будет зависеть от того, является ли это строковым массивом или одной строкой. Предполагая, что это одна строка, я бы рекомендовал такой подход
$regex = [regex]'(w _. )(?=(s[. ))'
$regex.Matches($block).value
Health_AEPOEP_Membership_Summary - Dev
Health_AEPOEP_YoY_Comparison_Summary - Dev
Подробности регулярного выражения
То же, что и выше, но добавлено следующее
(?=)
— Смотрите вперед
s[.
— сопоставьте пробел, левую квадратную скобку, один или несколько символов
Просто добавьте присваивание переменной $strings =
перед любым из них, чтобы захватить выходные данные. Либо будет работать с одной, либо с 500 книгами.
Комментарии:
1. Хм … когда я запускаю второй вариант, кажется
[Project...]
, что часть остается. Когда я выполняю первое предложение, удаляется только символ ], а не все остальное в скобках. Почему это должно быть? РЕДАКТИРОВАТЬ: первое решение работает, когда я добавляю пробел после- Dev
в выражении регулярного выражения.