用字母替换数字 - powershell
Replace numbers with letters - powershell
我有一个数组元素,我正在尝试用字母替换所有数字。这是操作前的数组元素:
$a[0].object
--- OUTPUT ---
518773112
我将数字转换为字符串并存储在$e
中。然后我找到该字符串的长度并将其存储在 $d
中
$e = $a[0].object.ToString()
$d = $a[0].object.ToString().length
$e
$d
---OUTPUT---
518773112
9
然后我尝试遍历字符串以用字母替换数字。我将 $i
放在子字符串中以获取我要替换的数字。然后我使用 if-statement
查看该子字符串是否等于数字,如果是,然后我使用替换方法尝试用字母替换数字。
for($i=0; $i -lt $d; $i++){
$pos = $e.Substring($i,1)
if($pos -eq '0'){$e += $pos.replace('0', 'A')}
if($pos -eq '1'){$e += $pos.replace('1', 'B')}
if($pos -eq '2'){$e += $pos.replace('2', 'C')}
if($pos -eq '3'){$e += $pos.replace('3', 'D')}
if($pos -eq '4'){$e += $pos.replace('4', 'E')}
if($pos -eq '5'){$e += $pos.replace('5', 'F')}
if($pos -eq '6'){$e += $pos.replace('6', 'G')}
if($pos -eq '7'){$e += $pos.replace('7', 'H')}
if($pos -eq '8'){$e += $pos.replace('8', 'I')}
if($pos -eq '9'){$e += $pos.replace('9', 'J')}
}
我的问题是,它会将字母连接到数字字符串的末尾:
518773112FBIHHDBBC
可能,因为我 if-statement
的 then
部分有 +=
。但是,当我将 +=
替换为 =
时,我的 Substring 方法出现错误:
Exception calling "Substring" with "2" argument(s): "startIndex cannot be larger than length of string.
我检查了 $i
和 $d
,它们在我 运行 循环之前设置正确。所以,我有点困惑。我错过了什么?
String.Replace()
方法将为您替换任何匹配字符或子字符串,您无需处理(甚至不关心)字符串中的每个位置分别:
$e = '518773112'
foreach($digit in 0..9){
# calculate next letter character
$substitute = ($digit + 'A'[0]) -as [char]
# replace all instances of $digit with $substitute
$e = $e.Replace("$digit", $substitute)
}
$e
的值现在是“FBIHHDBBC”
注意,此示例假定值仅为整数。
这是一种方法,首先生成一个从 A
到 J
的字符集,然后拆分 .object
属性 的值以生成一个这些数字的数组,然后我们可以在字符集上用于 indexing:
$char = [char[]]([char]'A'..[char]'J')
$a = [pscustomobject]@{
object = 518773112
}
$transform = $a.object.ToString() -split '' -ne ''
$a.object = [string]::new($char[$transform])
结果应该是:
PS /> $a
object
------
FBIHHDBBC
$e
会显示为 concatenated ,这是因为你通过循环连接了 $e
。
函数 subString
return 复制 $e
的副本。
你应该声明一个新的变量,
$a[0] = 518773112;
$e = $a[0].ToString()
$d = $a[0].ToString().length
$str = ""
for($i=0; $i -lt $d; $i++){
$pos = $e.Substring($i,1)
if($pos -eq '0'){$str += $pos.replace('0', 'A')}
if($pos -eq '1'){$str += $pos.replace('1', 'B')}
if($pos -eq '2'){$str += $pos.replace('2', 'C')}
if($pos -eq '3'){$str += $pos.replace('3', 'D')}
if($pos -eq '4'){$str += $pos.replace('4', 'E')}
if($pos -eq '5'){$str += $pos.replace('5', 'F')}
if($pos -eq '6'){$str += $pos.replace('6', 'G')}
if($pos -eq '7'){$str += $pos.replace('7', 'H')}
if($pos -eq '8'){$str += $pos.replace('8', 'I')}
if($pos -eq '9'){$str += $pos.replace('9', 'J')}
}
Write-Output $str;
尽管有更好的方法来完成同样的工作
要通过单个 regex-based
-replace
操作为现有的有用答案添加简洁的替代方法:
# PowerShell (Core) 7+ only.
# -> 'FBIHHDBBC'
'518773112' -replace '\d', { [char] ([int] [char] 'A' + [int] $_.Value) }
# Windows PowerShell alternative:
# (requires direct use of underlying .NET APIs)
[regex]::Replace('518773112', '\d', { param($m) [char] ([int] [char] 'A' + [int] $m.Value) })
正则表达式转义序列 \d
匹配任何单个十进制数字。
[int] [char] 'A' + [int] $_.Value
将捕获的数字 ($_.Value
) 的值作为整数添加到字符 A
的整数表示中,即它向A
.
的 Unicode 代码点
结果代码点然后是 re-converted 到一个字符 ([char]
),这会产生感兴趣的字母。
至于你试过的:
抛开你的方法效率低下,问题是你试图在与 input[=55= 相同的变量中构建你的 result 字符串] 字符串:
+=
因此 将所需结果附加到输入字符串
- 只是
=
本质上 将输入字符串替换为正在处理的单个字符,导致后续 .Substring()
调用失败,因为字符串现在是减少到单个字符。
立即 修复将在 新变量 中构建结果(但请注意答案中提供的所有解决方案这里最好):
$e = '518773112'
$d = $e.Length
$result = '' # initialize result string
for($i=0; $i -lt $d; $i++){
$pos = $e.Substring($i,1)
# Use += on *$result*
if($pos -eq '0'){$result += $pos.replace('0', 'A')}
if($pos -eq '1'){$result += $pos.replace('1', 'B')}
if($pos -eq '2'){$result += $pos.replace('2', 'C')}
if($pos -eq '3'){$result += $pos.replace('3', 'D')}
if($pos -eq '4'){$result += $pos.replace('4', 'E')}
if($pos -eq '5'){$result += $pos.replace('5', 'F')}
if($pos -eq '6'){$result += $pos.replace('6', 'G')}
if($pos -eq '7'){$result += $pos.replace('7', 'H')}
if($pos -eq '8'){$result += $pos.replace('8', 'I')}
if($pos -eq '9'){$result += $pos.replace('9', 'J')}
}
$result # Output the result: -> 'FBIHHDBBC'
这是我的两分钱:
-join ('518773112' -split '(.)' -ne '' | Foreach-Object { [char]([int]$_ + 65)})
结果:
FBIHHDBBC
替代 Select-Object
:
-join ('518773112' -split '(.)' -ne '' | Select-Object @{Name = 'Chr'; Expression = {[char]([int]$_ + 65)}}).Chr
另一个简洁的(灵感来自):
-join '518773112'.ToCharArray().ForEach{[char]([int]$_ + 17)}
这个converts the input string into a char array, then loops over each character using PowerShell's intrinsic method ForEach
.
在ForEach
的脚本块中,字符的代码点递增到数字范围'0'
..'9'
,然后转换回字符. “魔术”数字 17
只是字符 'A'
和 '0'
的代码点之间的差异(即 [int][char]'A' - [int][char]'0'
输出 17
)。
最后,-join
运算符的一元形式用于从各个字符创建单个字符串。
我有一个数组元素,我正在尝试用字母替换所有数字。这是操作前的数组元素:
$a[0].object
--- OUTPUT ---
518773112
我将数字转换为字符串并存储在$e
中。然后我找到该字符串的长度并将其存储在 $d
$e = $a[0].object.ToString()
$d = $a[0].object.ToString().length
$e
$d
---OUTPUT---
518773112
9
然后我尝试遍历字符串以用字母替换数字。我将 $i
放在子字符串中以获取我要替换的数字。然后我使用 if-statement
查看该子字符串是否等于数字,如果是,然后我使用替换方法尝试用字母替换数字。
for($i=0; $i -lt $d; $i++){
$pos = $e.Substring($i,1)
if($pos -eq '0'){$e += $pos.replace('0', 'A')}
if($pos -eq '1'){$e += $pos.replace('1', 'B')}
if($pos -eq '2'){$e += $pos.replace('2', 'C')}
if($pos -eq '3'){$e += $pos.replace('3', 'D')}
if($pos -eq '4'){$e += $pos.replace('4', 'E')}
if($pos -eq '5'){$e += $pos.replace('5', 'F')}
if($pos -eq '6'){$e += $pos.replace('6', 'G')}
if($pos -eq '7'){$e += $pos.replace('7', 'H')}
if($pos -eq '8'){$e += $pos.replace('8', 'I')}
if($pos -eq '9'){$e += $pos.replace('9', 'J')}
}
我的问题是,它会将字母连接到数字字符串的末尾:
518773112FBIHHDBBC
可能,因为我 if-statement
的 then
部分有 +=
。但是,当我将 +=
替换为 =
时,我的 Substring 方法出现错误:
Exception calling "Substring" with "2" argument(s): "startIndex cannot be larger than length of string.
我检查了 $i
和 $d
,它们在我 运行 循环之前设置正确。所以,我有点困惑。我错过了什么?
String.Replace()
方法将为您替换任何匹配字符或子字符串,您无需处理(甚至不关心)字符串中的每个位置分别:
$e = '518773112'
foreach($digit in 0..9){
# calculate next letter character
$substitute = ($digit + 'A'[0]) -as [char]
# replace all instances of $digit with $substitute
$e = $e.Replace("$digit", $substitute)
}
$e
的值现在是“FBIHHDBBC”
注意,此示例假定值仅为整数。
这是一种方法,首先生成一个从 A
到 J
的字符集,然后拆分 .object
属性 的值以生成一个这些数字的数组,然后我们可以在字符集上用于 indexing:
$char = [char[]]([char]'A'..[char]'J')
$a = [pscustomobject]@{
object = 518773112
}
$transform = $a.object.ToString() -split '' -ne ''
$a.object = [string]::new($char[$transform])
结果应该是:
PS /> $a
object
------
FBIHHDBBC
$e
会显示为 concatenated ,这是因为你通过循环连接了 $e
。
函数 subString
return 复制 $e
的副本。
你应该声明一个新的变量,
$a[0] = 518773112;
$e = $a[0].ToString()
$d = $a[0].ToString().length
$str = ""
for($i=0; $i -lt $d; $i++){
$pos = $e.Substring($i,1)
if($pos -eq '0'){$str += $pos.replace('0', 'A')}
if($pos -eq '1'){$str += $pos.replace('1', 'B')}
if($pos -eq '2'){$str += $pos.replace('2', 'C')}
if($pos -eq '3'){$str += $pos.replace('3', 'D')}
if($pos -eq '4'){$str += $pos.replace('4', 'E')}
if($pos -eq '5'){$str += $pos.replace('5', 'F')}
if($pos -eq '6'){$str += $pos.replace('6', 'G')}
if($pos -eq '7'){$str += $pos.replace('7', 'H')}
if($pos -eq '8'){$str += $pos.replace('8', 'I')}
if($pos -eq '9'){$str += $pos.replace('9', 'J')}
}
Write-Output $str;
尽管有更好的方法来完成同样的工作
要通过单个 regex-based -replace
操作为现有的有用答案添加简洁的替代方法:
# PowerShell (Core) 7+ only.
# -> 'FBIHHDBBC'
'518773112' -replace '\d', { [char] ([int] [char] 'A' + [int] $_.Value) }
# Windows PowerShell alternative:
# (requires direct use of underlying .NET APIs)
[regex]::Replace('518773112', '\d', { param($m) [char] ([int] [char] 'A' + [int] $m.Value) })
正则表达式转义序列
\d
匹配任何单个十进制数字。
的 Unicode 代码点[int] [char] 'A' + [int] $_.Value
将捕获的数字 ($_.Value
) 的值作为整数添加到字符A
的整数表示中,即它向A
.结果代码点然后是 re-converted 到一个字符 (
[char]
),这会产生感兴趣的字母。
至于你试过的:
抛开你的方法效率低下,问题是你试图在与 input[=55= 相同的变量中构建你的 result 字符串] 字符串:
+=
因此 将所需结果附加到输入字符串- 只是
=
本质上 将输入字符串替换为正在处理的单个字符,导致后续.Substring()
调用失败,因为字符串现在是减少到单个字符。
立即 修复将在 新变量 中构建结果(但请注意答案中提供的所有解决方案这里最好):
$e = '518773112'
$d = $e.Length
$result = '' # initialize result string
for($i=0; $i -lt $d; $i++){
$pos = $e.Substring($i,1)
# Use += on *$result*
if($pos -eq '0'){$result += $pos.replace('0', 'A')}
if($pos -eq '1'){$result += $pos.replace('1', 'B')}
if($pos -eq '2'){$result += $pos.replace('2', 'C')}
if($pos -eq '3'){$result += $pos.replace('3', 'D')}
if($pos -eq '4'){$result += $pos.replace('4', 'E')}
if($pos -eq '5'){$result += $pos.replace('5', 'F')}
if($pos -eq '6'){$result += $pos.replace('6', 'G')}
if($pos -eq '7'){$result += $pos.replace('7', 'H')}
if($pos -eq '8'){$result += $pos.replace('8', 'I')}
if($pos -eq '9'){$result += $pos.replace('9', 'J')}
}
$result # Output the result: -> 'FBIHHDBBC'
这是我的两分钱:
-join ('518773112' -split '(.)' -ne '' | Foreach-Object { [char]([int]$_ + 65)})
结果:
FBIHHDBBC
替代 Select-Object
:
-join ('518773112' -split '(.)' -ne '' | Select-Object @{Name = 'Chr'; Expression = {[char]([int]$_ + 65)}}).Chr
另一个简洁的(灵感来自
-join '518773112'.ToCharArray().ForEach{[char]([int]$_ + 17)}
这个converts the input string into a char array, then loops over each character using PowerShell's intrinsic method ForEach
.
在ForEach
的脚本块中,字符的代码点递增到数字范围'0'
..'9'
,然后转换回字符. “魔术”数字 17
只是字符 'A'
和 '0'
的代码点之间的差异(即 [int][char]'A' - [int][char]'0'
输出 17
)。
最后,-join
运算符的一元形式用于从各个字符创建单个字符串。