Поскольку вы ищете пары ключ-значение , имеет смысл собрать их в (упорядоченном n) хеш-таблице .
Разделение может быть выполнено с помощью оператора -split
на основе регулярных выражений, который также позволяет включать части того, что соответствует разделителю регулярное выражение , в выходной массив,через группы захвата ((...)
).
# Input string
$s = '(01) this is value one (02) and this is 2 (03) and this is number 3'
# Initialize the output hashtable
$ht = [ordered] @{}
# Split the input string and fill the hashtable.
$i = 0;
$s -split '(\(\d+\)) ' -ne '' | ForEach-Object {
if (++$i % 2) { $key = $_ } else { $ht[$key] = $_ }
}
# Output the hashtable
$ht
Выше приведены значения:
Name Value
---- -----
(01) this is value one
(02) and this is 2
(03) and this is number 3
Примечание: Если вы не хотите включать в ключ включающий (...)
(name), используйте
-split '\((\d+)\) '
вместо -split '(\(\d+\)) '
В приведенном выше примере строка разбивается на элементы массива, в которых пары смежных элементов представляют пары ключ-значение.Затем вызов ForEach-Object
добавляет эти пары ключ-значение в выходную хеш-таблицу, решая, является ли входной элемент ключом или значением на основе того, является ли индекс элемента нечетным или четным.
Что касается что вы пытались :
Ваше регулярное выражение '(\(\d\d\))(.*)'
слишком жадный , что означает, что одно совпадение в данной строке будет соответствовать всему строка из-за подвыражения .*
.
Вы получите желаемые совпадения, если вместо этого будете использовать следующее регулярное выражение:
'(\(\d+\)) ([^(]+)'
То есть после сопоставлениятакие индексы, как (01)
соответствуют только до, но не включая последующие (
, если таковые имеются.
В контексте упрощенной версии вашей исходной команды , которая выводит пары ключ-значение в виде массива пользовательских объектов ([pscustomobject]
экземпляров):
$s = '(01) this is value one (02) and this is 2 (03) and this is number 3'
$pattern = '(\(\d+\)) ([^(]+)'
$s | Select-String $pattern -AllMatches | ForEach-Object {
$_.matches | Select-Object @{ n='Name'; e = { $_.Groups[1].Value } },
@{ n='Value'; e = { $_.Groups[2].Value } }
}
Приведенные выше выходы:
Name Value
---- -----
(01) this is value one
(02) and this is 2
(03) and this is number 3
Обратите внимание, однако, что вышеприведенный вывод массив из пользовательских объектов , каждый из которых представляет значение ключаpair, которая отличается от решения в верхнем разделе, который создает одну хеш-таблицу, содержащую все пары ключ-значение.