Powershell регулярное выражение для строки между двумя специальными символами - PullRequest
0 голосов
/ 08 февраля 2019

Имя файла, как показано ниже

$inpFiledev = "abc_XYZ.bak"

Мне нужно только XYZ в переменной для сравнения с другим именем файла.я попробовал ниже:

[String]$findev = [regex]::match($inpFiledev ,'_*.').Value
Write-Host $findev

Ответы [ 4 ]

0 голосов
/ 08 февраля 2019

В дополнение к полезному ответу mjsqu с двумя идиоматическими альтернативами PowerShell:

Обзор того, как регулярные выражения (регулярные выражения) используются в PowerShellсм. Get-Help about_regular_expressions.


Использование -split для разделения на _ и ., извлечение среднего элемента результирующего 3-элементного массива:

PS> ("abc_XYZ.bak" -split '[_.]')[1]
XYZ
  • -split (первый) операнд RHS является регулярным выражением;regex [_.] - это набор символов ([...]), который соответствует одиночному символу. , который является либо литералом _, либо литералом . Поэтому введите abc_XYZ.bak разбивается на массив, содержащий строки abc, XYZ и bak.При применении индекса [1] извлекается средний токен, XYZ.

Использование -replace для извлечения интересующего токена через группу захвата ((...), упоминаемую воперанд замены как $1):

PS> "abc_XYZ.bak" -replace '^.+_([^.]+).+$', '$1'
XYZ
  • -replace тоже работает с регулярным выражением в качестве первого операнда RHS - что заменить - тогда как второй операнд определяет, что заменитьсовпавшая (вспомогательная) строка с .

  • Regex ^.+_([^.]+).+$:

    • ^.+_ соответствует одному или нескольким (+) символов (.) в начале ввода (^) - обратите внимание, как . - используется вне набора символов ([...]) - это регулярное выражение метасимвол который представляет любой символ (в строке ввода из одной строки).

    • ([^.]+) является группой захвата ((...))которая соответствует отрицательному символьному набору ([^...]): [^.] соответствует любому буквенному символу.что не является литералом ., один или несколько раз (+).

    • Все, что соответствует подвыражению внутри (...), может бытьупоминается в операнде замены как $<n>, где <n> представляет основанный на 1 индекс группы захвата в регулярном выражении;в этом случае $1 может использоваться для ссылки на эту первую (и единственную) группу захвата.

    • .+$ соответствует одному или нескольким (+) оставшимся символам (.) до тех пор, пока не будет достигнут конец ввода ($).

  • Операнд-заменитель $1 просто относится к тому, с чем совпала первая группа захвата;в этом случае: XYZ.

    • Для полного обзора синтаксиса -replace замещающих операндов см. этот ответ .
0 голосов
/ 08 февраля 2019

Поскольку вы используете ускоритель [regex], вам нужна обратная косая черта, чтобы избежать конца . (если вы хотите соответствовать ему), и вам нужна точка перед звездочкой, чтобы соответствовать любым символам после подчеркивания.Если все символы между ними являются буквами, используйте \w+

$findev = [regex]::match($inpFiledev ,'_.*\.')
$findev
_XYZ.
0 голосов
/ 08 февраля 2019

это демонстрирует два других способа получить нужную информацию из строки образца.1-й использует базовый метод .Split() string для необработанной строки.2-й предполагает, что вы имеете дело с файловыми объектами, и начинает с получения .BaseName для файла.это уже удаляет расширение, так что вам не нужно делать это самостоятельно.

Если вы имеете дело с большим числом строк, а не с файловыми объектами, то предыдущие ответы на регулярные выражения, скорее всего, будут быстрее.[ ухмылка ]

$inpFiledev = 'abc_XYZ.bak'
$findev = $inpFiledev.Split('.')[0].Split('_')[-1]

# fake reading in a file with Get-Item or Get-ChildItem
$File = [System.IO.FileInfo]'c:\temp\testing\abc_XYZ.bak'
$WantedPart = $File.BaseName.Split('_')[-1]

'split on a string         = {0}' -f $findev
'split on BaseName of file = {0}' -f $WantedPart

вывод ...

split on a string         = XYZ
split on BaseName of file = XYZ
0 голосов
/ 08 февраля 2019

Звездочки в регулярном выражении не ведут себя так же, как в командах перечисления файловой системы.В своем нынешнем виде ваше регулярное выражение ищет подчеркивание, повторяется ноль или более раз, за ​​которым следует любой символ (представленный в регулярном выражении точкой).Таким образом, регулярное выражение находит нулевые подчеркивания прямо в начале строки, затем находит 'a', и это совпадает с возвращаемым значением.

Сначала исправьте этот бит:

'_*.'

Становится«подчеркивание, за которым следует любое количество символов, за которым следует буквальный период».«Буквальный период» означает, что нам нужно выйти из периода в регулярном выражении, используя \., запоминание этого периода означает любой символ:

'_.*\.'
  • _ подчеркивание
  • .* любое количество символов
  • \. буквальный период

Возвращает:

_XYZ.

Итак, не далекоoff.

Если вы хотите вернуть что-то между символами, вам нужно использовать группы захвата.Поставьте круглые скобки вокруг бита, который вы хотите сохранить:

'_(.*)\.'

Затем вам нужно использовать группы регулярных выражений PowerShell, чтобы получить значение:

[regex]::match($inpFiledev ,'_(.*)\.').Groups[1].Value

, которое возвращает: XYZ

Число 1 в Группах [1] означает только первую группу захвата, вы можете добавить столько выражений, сколько захотите, используя больше скобок, но в этом случае вам нужна только одна.

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