Как изменить регистр обратных ссылок? - PullRequest
3 голосов
/ 25 июля 2011

Я пытаюсь изменить обратную ссылку в PowerShell, но мне не везет: (

Это мой пример:

"456,Jane Doe" -replace '^(\d{3}),(.*)$',"| $(`"`$2`".ToUpper()) | `$1 |"

Если я его запускаю, я получаю следующее:

| Jane Doe | 456 |

Но я действительно ожидаю этого:

| JANE DOE | 456 |

Если я запусту следующее (то же, что и выше, но без '()' при вызове ToUpper):

"456,Jane Doe" -replace '^(\d{3}),(.*)$',"| $(`"`$2`".ToUpper) | `$1 |"

Я получаю это:

| string ToUpper(), string ToUpper(System.Globalization.CultureInfo culture) | 456 |

Таким образом, похоже, что PowerShell знает, что обратная ссылка«$ 2» - это строка, но почему я не могу заставить PowerShell преобразовать ее в верхний регистр?

Терри

Ответы [ 2 ]

3 голосов
/ 25 июля 2011
[Regex]::Replace('456,Jane Doe',
    '^(\d{3}),(.*)$',
    {
        param($m)
        '| ' + $m.Groups[2].Value.ToUpper() + ' | ' + $m.Groups[1].Value + ' |'
    }
)

Признаюсь, не очень красиво.И, к сожалению, вы не можете использовать блоки скриптов в качестве замены в операторе -replace.

0 голосов
/ 03 марта 2012

Просто чтобы объяснить, что происходит, в "| <strong>$(&#x0060;"&#x0060;$2&#x0060;".ToUpper())</strong> | &#x0060;$1 |" PowerShell оценивает выделенное подвыражение до передачи строки оператору -replace, а не после того, как произошла операция замены.

Другими словами, ToUpper вызывается для строкового значения $2, в результате чего | $2 | $1 | используется для операции замены. Это можно увидеть, включив в строку подвыражения букву, например:

"456,Jane Doe" -replace '^(\d{3}),(.*)$',"| $(`"zz `$2`".ToUpper()) | `$1 |"

Имеет эффективную строку замены | ZZ $2 | $1 |, в результате чего получается | ZZ Jane Doe | 456 |.


Аналогично, вторая версия без круглых скобок, "| <strong>$(&#x0060;"&#x0060;$2&#x0060;".ToUpper)</strong> | &#x0060;$1 |", оценивается как "some string".ToUpper, что помещает массив определений перегрузки для метода ToUpper в System.String в строке замены.


Чтобы сохранить операцию замены как однострочную, ответ Джоуи с использованием перегрузки MatchEvaluator на Regex.Replace работает хорошо. Или вы можете выполнить форматирование строки самостоятельно, основываясь на результатах -match:

if( '456,Jane Doe' -match '^(\d{3}),(.*)$' ) {
  '| {0} | {1} |' -f $matches[2].ToUpper(),$matches[1]
}

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

PS> $r = '| {0} | {1} |' -f $matches[2].ToUpper(),$matches[1]
PS> 'A longer string with 456,Jane Doe in it.'.Replace( $matches[0], $r )
A longer string with | JANE DOE | 456 | in it.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...