Как получить значение в объекте powershell в моем операторе замены? - PullRequest
0 голосов
/ 01 марта 2019

Попытка использовать карту объектов для замены названия месяца номером месяца.Случай использования: я пытаюсь переименовать файлы, содержащие имена месяцев.

$monthNameToNumberMap = @{
  January = '01'
  February = '02'
  March = '03'
  April = '04'
  May = '05'
  June = '06'
  July = '07'
  August = '08'
  September = '09'
  October = '10'
  November = '11'
  December = '12'
}

Write-Host "Desired : 02 20 => ";
"February 20" -Replace '([A-z]{3,9}) (\d{2})', "$monthNameToNumberMap[`$1] `$2"

Write-Host "Desired : 05 03 => ";
"May 03" -Replace '([A-z]{3,9}) (\d{2})', "$monthNameToNumberMap[`$1] `$2"

# receiving : @{January=01; February=02; March=03; April=04; May=05; June=06; July=07; August=08; September=09; October=10; November=11; December=12}[February] 20

Мне не удается получить доступ к значению карты объектов с помощью группы совпадений регулярных выражений.

Ответы [ 3 ]

0 голосов
/ 01 марта 2019

вот несколько другой способ сделать работу.[ ухмылка ] использует встроенный список .MonthNames для преобразования названия месяца в число.

если вам нужно, чтобы это было культурно-инвариантным, вы можете использовать [System.Globalization.DateTimeFormatInfo]::InvariantInfo.MonthNames вместо Get-Culture списка.

$DateStringList = @(
    'February 20'
    'January 3'
    'August 14'
    'June 19'
    )
$MonthNameList = (Get-Culture).DateTimeFormat.MonthNames

foreach ($DSL_Item in $DateStringList)
    {
    $MonthName, [int]$DayNumber = $DSL_Item.Split(' ')
    $MonthNumber = $MonthNameList.IndexOf($MonthName) + 1
    'Source date  = {0}' -f $DSL_Item
    '{0} is month # {1}' -f $MonthName, $MonthNumber
    'Numeric date = {0:D2}/{1:D2}' -f $MonthNumber, $DayNumber
    '=' * 20
    }

output ...

Source date  = February 20
February is month # 2
Numeric date = 02/20
====================
Source date  = January 3
January is month # 1
Numeric date = 01/03
====================
Source date  = August 14
August is month # 8
Numeric date = 08/14
====================
Source date  = June 19
June is month # 6
Numeric date = 06/19
====================
0 голосов
/ 02 марта 2019

Полезный ответ Wiktor Stribiżew работает во всех версиях PowerShell.

В PowerShell Core (v6.1 и выше) у вас сейчас может решить проблему, используя -replace, а именно, передав блок сценария в качестве операнда замены:

"February 20" -replace '\b([A-z]{3,9}) (\d{2})\b', { 
  $monthNameToNumberMap[$_.Groups[1].Value] + ' ' + $_.Groups[2].Value
}

$_ внутри блока сценария являетсясовпадение под рукой, как экземпляр System.Text.RegularExpressions.Match.
Вывод блока скрипта используется в качестве строки замены.

0 голосов
/ 01 марта 2019

Вы пытаетесь оценить значение обратной ссылки в шаблоне замены строки, что невозможно.Вам необходимо определить обратный вызов и передать его методу [regex]::Replace:

$regex = [regex]'\b([A-Za-z]{3,}) (\d{2})\b'
$callback = {  param($m) $monthNameToNumberMap[$m.Groups[1].Value] + " " + $m.Groups[2].Value }
$regex.Replace("February 20", $callback)

Обратите внимание, что [A-z] соответствует больше, чем просто буквы , поэтому рекомендуется использовать [a-zA-Z].

Я также добавил границы слов, чтобы избежать совпадения строк, таких как AAAAAAAAAA 2222222222222222.

enter image description here

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