Как использовать переменную как часть регулярного выражения в PowerShell? - PullRequest
0 голосов
/ 07 мая 2018

Я хочу Select-String части пути к файлу, начиная со строкового значения, которое содержится в переменной.Позвольте мне объяснить это в абстрактном примере.

Давайте предположим, что этот путь: / docs / reports / test reports / document1.docx

Используя regex, я могу получить требуемую строку следующим образом: '^.*(?=\/test\s)'

https://regex101.com/r/6mBhLX/5

Результирующая строка '/ test reports / document1.docx'.

Теперь, чтобы это работало, я должен использовать буквальную строку 'тестовое задание'.Тем не менее, я хотел бы знать, как использовать переменную, которая содержит 'test', например, $ myString.

Я уже смотрел на Как вы используете переменную в регулярном выражении? , ноЯ не мог понять, как адаптировать это для PowerShell.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 07 мая 2018


Просто напишите переменную в двойных кавычках («шаблон»), например:

PS > $pattern = "^\d+\w+"
PS > "357test*&(fdnsajkfj" -match $pattern          # return true
PS > "357test*&(fdnsajkfj" -match "$pattern.*\w+$"  # return true
PS > "357test*&(fdnsajkfj" -match "$pattern\w+$"    # return false

Пожалуйста, попробуйте. :)

0 голосов
/ 07 мая 2018

Полезный ответ Wiktor Stribiżew дает ключевой указатель:

Используйте [regex]::Escape(), чтобы избежать строки для безопасного включения в регулярное выражение (регулярное выражение), чтобы она воспринималась как литерал ;
например, [regex]::Escape('$10?') возвращает \$10\? - символы с особым значением для регулярного выражения были \ -экранированы.

Однако, Я предлагаю использовать '...', т. Е. Строить регулярное выражение из одиночных строк в кавычках:

$myString='test'
$regex = '^.*(?=/' + [regex]::escape($myString) + '\s)'

Использование оператора -f - $regex = '^.*(?=/{0}'\s)' -f [regex]::Escape($myString) тоже работает и, возможно, визуально чище, но учтите, что -f - в отличие от конкатенации строк с + - чувствительно к культуре - , что может привести к разным результатам.

Использование '...' строк в контексте регулярных выражений в PowerShell - хорошая привычка для формирования :

  • Избегая "...", вы избегаете дополнительной предварительной интерпретации (интерполяции или расшифровки) строки, которая может иметь неожиданные эффекты, учитывая, что $ имеет особое значение в обоих контексты: начало ссылка на переменную или подвыражение при раскрытии строки и маркер конца ввода в регулярных выражениях.

  • Использование "..." может быть особенно сложно в строке замены оператора -replace на основе регулярных выражений, где токены, такие как $1, относятся к результатам группы захвата, а если вы использовали "$1", PowerShell попытается развернуть переменную $1 , которая предположительно не существует, что приведет к пустой строке .

0 голосов
/ 07 мая 2018

Я предлагаю использовать $([regex]::escape($myString)) внутри строкового литерала в двойных кавычках:

$myString="[test]"
$pattern = "^.*(?=/$([regex]::escape($myString))\s)"

Или, если вы не хотите беспокоиться о дополнительном экранировании, используйте обычную конкатенацию с использованием оператора +:

$pattern = '^.*(?=/' + [regex]::escape($myString) +'\s)'

Получившийся $pattern будет выглядеть как ^.*(?=/\[test]\s). Поскольку переменная $myString является литеральной строкой, вам нужно экранировать все специальные метасимволы регулярных выражений (с [regex]::escape()), которые могут быть внутри нее, чтобы механизм регулярных выражений интерпретировал ее как буквенные символы.

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

$s = '/docs/reports/test reports/document1.docx'
$myString="test"
$pattern = "^.*(?=/$([regex]::escape($myString))\s)"
$s -replace $pattern

Результат: /test reports/document1.docx

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