Вы можете изменить хеш-таблицу $test
на месте следующим образом:
foreach($key in @($test.Keys)) { # !! @(...) is required - see below.
$value = $test[$key] # save value
$test.Remove($key) # remove old entry
# Recreate the entry with the transformed name.
$test[($key -creplace '(?<!^)\p{Lu}', '_$&').ToUpper()] = $value
}
@($test.Keys)
создает массив из существующих ключей хеш-таблицы;@(...)
гарантирует, что коллекция ключей будет скопирована в статический массив , поскольку использование свойства .Keys
непосредственно в цикле, который изменяет ту же самую хеш-таблицу, прервется.
Тело цикла сохраняетзначение для ключа ввода под рукой, а затем удаляет запись под старым именем. [1]
Запись затем воссоздается под новым именем ключа с использованием требуемого преобразования имени:
$key -creplace '(?<!^)\p{Lu}
соответствует каждой заглавной букве (\p{Lu}
) в данном ключе, кроме начала строки ((?<!^)
), и заменяет ее на _
, за которым следует эта буква (_$&
);преобразование результата в верхний регистр (.ToUpper()
) дает желаемое имя.
[1] Удаление старой записи перед добавление переименованной позволяет избежать проблем с однословные имена, такие как Simplest
, чье преобразованное имя SIMPLEST
считается таким же именем из-за нечувствительности к регистру hasthables в PowerShell.Таким образом, присвоение значения записи SIMPLEST
, пока запись Simplest
все еще существует, фактически нацеливается на существующую запись , и последующая $test.Remove($key)
просто удалит эту запись, не добавив новую.
Наконечник шляпы JosefZ за указание на проблему.