Powershell найти строку между символами и заменить

В скрипте Powershell у меня Hashtable содержит личную информацию. Hashtable выглядит как

{first = "James", last = "Brown", phone = "12345"...}

Используя эту хэш-таблицу, я хотел бы заменить строки в текстовом файле шаблона. Для каждой строки, совпадающей с форматом @key@, я хочу заменить эту строку на значение, соответствующее ключу в хеш-таблице. Вот пример ввода и вывода:

input.txt

My first name is @first@ and last name is @last@. 
Call me at @phone@

output.txt

My first name is James and last name is Brown. 
Call me at 12345  

Не могли бы вы посоветовать мне, как вернуть строку "ключ" между "@", чтобы я мог найти их значение для функции замены строки? Любые другие идеи по этой проблеме приветствуются.

2 ответа

Решение

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

$tmpl = 'My first name is @first@ and last name is @last@. 
Call me at @phone@'

$h = @{
    first = "James"
    last = "Brown"
    phone = "12345"
}

$new = $tmpl

foreach ($key in $h.Keys) {
    $escKey = [Regex]::Escape($key)
    $new = $new -replace "@$escKey@", $h[$key]
}

$new

объяснение

$tmpl содержит строку шаблона.

$h это хеш-таблица

$new будет содержать замененную строку.

  1. Перечислим все ключи в хэше.
  2. Мы храним экранированную версию ключа в регулярном выражении $escKey,
  3. Мы заменяем $escKey окружен @ символы с поиском по хеш-таблице для конкретного ключа.

Одна из приятных вещей в этом состоит в том, что вы можете изменить свою хеш-таблицу и шаблон, и вам никогда не придется обновлять регулярное выражение. Он также будет корректно обрабатывать случаи, когда ключ не имеет соответствующего сменного раздела в шаблоне (и наоборот).

Вы можете создать шаблон, используя расширяемую (двойные кавычки) здесь-строку:

$Template = @"
My first name is $($hash.first) and last name is $($hash.last). 
Call me at $($hash.phone)
"@

$hash = @{first = "James"; last = "Brown"; phone = "12345"}

$Template

My first name is James and last name is Brown. 
Call me at 12345
Другие вопросы по тегам