Регулярное выражение для определения местоположения одной строки, появляющейся в любом месте после другой, но перед чем-то

#regex #powershell #edi

#регулярное выражение #powershell #edi

Вопрос:

У меня есть файл EDI. Это та часть, о которой идет речь:

N1 * ST * ТЕСТ
N3 * АДРЕС
N4 * ГОРОД * УЛИЦА *
ПОЧТОВЫЙ ИНДЕКС * EM * ТЕСТ @GMAIL.COM
N1 * ПО * ТЕСТУ
N3 * АДРЕС
N4 * ГОРОД * УЛИЦА *
ПОЧТОВЫЙ ИНДЕКС * EM *TEST2@GMAIL.COM

Я использую powershell

 Get-ChildItem 'C:Temp*.edi' | Where-Object {(Select-String -InputObject $_ -Pattern 'PER*EM*w @w .w ' -List)}
 

Я хочу найти адрес электронной почты, который появляется после N1 * ST, но перед N1 * BY . У меня есть выражение, которое работает для адреса электронной почты, но я застрял на том, как получить только одно значение. Реальная проблема иногда заключается в том, что электронная почта есть, а иногда ее нет. Поэтому я действительно хочу игнорировать это второе электронное письмо после N1 *BY.

Заранее спасибо за помощь.

Комментарии:

1. N1*ST[sS] ?(w @w .w )[sS] ?N1*BY поместил бы его в группу захвата # 1 для вас regex101.com/r/lVcvWv/1

2. Я не знаком с PoweShell, но если он поддерживает поисковые запросы переменной ширины, то регулярное выражение можно было бы улучшить еще больше

Ответ №1:

Вы можете использовать

 (?s)(?<=N1*ST.*)PER*EM*w @w .w (?=.*N1*BY)
 

См . <a rel=»noreferrer noopener nofollow» href=»https:///regexstorm.net/tester?p=(?s)(?.Демонстрация регулярных выражений в СЕТИ.

Подробные сведения

  • (?s) — встроенный RegexOptions.Singleline модификатор регулярных выражений DOTALL (в .NET) . , также позволяющий сопоставлять символы новой строки
  • (?<=N1*ST.*) — положительный взгляд назад, который соответствует местоположению, которому непосредственно предшествует N1*ST
  • PER*EM* PER*EM* строка
  • w @w — символы 1 word, @ , и символы 1 word
  • . — точка
  • w — символы 1 word
  • (?=.*N1*BY) — положительный прогноз, который соответствует местоположению, за которым сразу следует N1*BY буквальная строка.

ПРИМЕЧАНИЕ: вам нужно прочитать содержимое файла с Get-Content $filepath -Raw помощью, чтобы найти правильное соответствие.

Что-то вроде

 Get-ChildItem 'C:Temp*.edi' | % { Get-Content $_ -Raw | Select-String -Pattern '(?s)(?<=N1*ST.*)PER*EM*w @w .w (?=.*N1*BY)' } | % { $_.Matches.value }