Powershell regex group соответствует регулярному выражению, но моей группы нет. Чего не хватает? - PullRequest
1 голос
/ 16 февраля 2020

У меня есть код, который я портирую из скрипта jenkins, и он мне нужен как команда оболочки. Итак, я знаю, что регулярное выражение работает - меня поражает то, как оно может соответствовать , но при этом не иметь мою группу захвата. Мне нужны только имена каталогов уровня root как таковые:

foo
baz

Как это может "соответствовать", но тогда не иметь мою группу? Кстати: если есть более простой способ добиться этого, я весь слух.

PS E:\SysData\Jenkins\workspace\chb0_chb0mb_example> git diff --name-only origin/master  feature/foo |  %{ Resolve-Path -Relative $_ } | sls  '.\\.*\\.*'  | sls '\\.\\(.+?)\\.*|.*' | %{$_.matches}


Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 48
Value    : .\foo\Nuget\deleteme.txt

Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 55
Value    : .\baz\QC_OH_DARKESol\deleteme.txt

Ответы [ 2 ]

2 голосов
/ 16 февраля 2020

Предполагая, что у меня есть правильный вопрос. Во-первых, буквальный период должен иметь обратную косую черту. Но все равно работает без обратной косой черты. Там нет backsla sh в начале. Не у всех есть команда git. Этот шаблон может быть короче, но это работает. Я расширяю свойство groups, которое вы не показывали.

'.\foo\Nuget\deleteme.txt' | sls '.\\(.+?)\\.*|.*' | % matches | % groups

Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 6
Value    : .\foo\

Success  : True
Name     : 1
Captures : {1}
Index    : 2
Length   : 3
Value    : foo

Передача объекта из первых слайсов во второй слайс что-то портит при захвате группы. Это похоже на ошибку. Отправлено: конвейерная строка выбора сама по себе и странный эффект от совпадений Свойство value здесь даже не так.

'abc' | select-string a | select-string '(b)' | % matches | % groups

Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 1
Value    : a   # should be b

Сравните с отправкой простой строки во второй select- строка, которая дает правильный вывод:

'abc' | select-string a | % line | select-string '(b)' | % matches | % groups

Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 1
Length   : 1
Value    : b

Success  : True
Name     : 1
Captures : {1}
Index    : 1
Length   : 1
Value    : b
1 голос
/ 16 февраля 2020

полезный ответ js2010 указывает на потенциальную проблему с вашим подходом (.\\ должно быть \.\\), кратко демонстрирует необъяснимое поведение, которое вы испытали (для которого они создали Проблема GitHub ) и предлагает обходной путь (вставка | % Line).

Для более непосредственного решения вашей проблемы:

# Inputs are sample paths.
'.\foo\Nuget\deleteme.txt',
'.\bar\QC_OH_DARKESol\deleteme.txt' | 
  foreach { if ($_ -match '^\.\\([^\\]+)') { $Matches[1] } }

Из приведенного выше получаются следующие строки:

foo
bar

То есть извлекает первый компонент пути после литерала .\ из путей ввода, используя foreach (ForEach-Object) для применения -match, оператор сопоставления регулярных выражений для каждой входной строки, результаты сопоставления которого отражены в автоматической переменной c $Matches, равной га sh таблица , чья запись 0 является общим соответствием, с записью 1, содержащей значение 1-й группы захвата, 2 2-й, ...; названные группы захвата (например, (?<root>...)), если они есть, имеют записи по имени (например, root).


Альтернативой является использование switch оператор с опцией -Regex:

switch -Regex (
  git diff --name-only origin/master feature/foo | Resolve-Path -Relative
) {
  '^\.\\([^\\]+)' { $Matches[1] } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...