String Powershell在位置x处替换字符
有一个字符串String Powershell在位置x处替换字符,string,performance,powershell,replace,String,Performance,Powershell,Replace,有一个字符串$s,大约2.5 KB长。 我需要在循环中运行一系列替换(大约20个)。 总共有一些像这样的800K字符串,所以我需要这个来加快速度。 对于每次替换,我都知道位置[int]$x和新值[string]$ns 例如: 我们从$s==“abcdefghijklmn”开始,$x(位置)是3,要放在那里的新值是$ns==“XYZ” 我们最终得到了$s==“abcXYZghijklmn” (字符串的索引基于0) 到目前为止,我的解决方案是: Powershell 5.x 这至少有三个操作:删除
$s
,大约2.5 KB长。
我需要在循环中运行一系列替换(大约20个)。
总共有一些像这样的800K
字符串,所以我需要这个来加快速度。
对于每次替换,我都知道位置[int]$x
和新值[string]$ns
例如:
我们从$s==“abcdefghijklmn”
开始,$x(位置)
是3,要放在那里的新值是$ns==“XYZ”
我们最终得到了$s==“abcXYZghijklmn”
(字符串的索引基于0)
到目前为止,我的解决方案是:
Powershell 5.x
这至少有三个操作:删除一个字符串,然后插入一个新字符串,最后存储最终结果(这里不确定内部结构,但我假设这就是工作原理)。对于每个长度为2.5KB的800K字符串,我们谈论的是在内存中三次处理约2GB的数据。这不是最有效的做事方式
在Python中,使用MutableString,我可以以最小的成本进行就地替换。Powershell中是否存在类似的东西?不如重新构建字符串
$s = "abcdefghijklmn"
$ns = "XYZ"
$x = 3
$s = $s.Remove($x, $ns.Length).Insert($x, $ns)
不确定它是否更快,可能值得检查您所有的字符串。您还可以与foreach并行运行,以加快流程。这应该更快。您应该在替换之前将输入字符串转换为字符数组一次,并在所有替换完成后将其转换回字符串:
$s.Substring(0,$x) + $ns + $s.Substring($x)
这是另一种选择。它使用正则表达式
$s = ("abcdefghijklmn").ToCharArray()
$ns = ("XYZ").ToCharArray()
$x = 3
0..($ns.Length-1) | ForEach-Object { $s[$x + $_] = $ns[$_] }
$result = [String]::new($s)
正则表达式详细信息:
您必须测试自己,在您的情况下,所提供的解决方案中哪一个是最快的。以下是我使用Stringbuilder类的看法
^ Assert position at the beginning of a line (at beginning of the string or after a line break character)
( Match the regular expression below and capture its match into backreference number 1
. Match any single character that is not a line break character
{3} Exactly 3 times
)
. Match any single character that is not a line break character
( Match the regular expression below and capture its match into backreference number 2
. Match any single character that is not a line break character
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
我会说不,PowerShell不是最快的语言。它是用于系统管理的,运行在一个相当“高的级别”有趣的是,在您发布答案之前,我提出了一个基于StringBuilder的解决方案。StringBuilder实现可变字符串可能是最自然的方法。做得好。
^ Assert position at the beginning of a line (at beginning of the string or after a line break character)
( Match the regular expression below and capture its match into backreference number 1
. Match any single character that is not a line break character
{3} Exactly 3 times
)
. Match any single character that is not a line break character
( Match the regular expression below and capture its match into backreference number 2
. Match any single character that is not a line break character
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
$s = "abcdefghijklmn" -as [system.text.stringbuilder]
$ns = "XYZ"
$x = 3
$s.Replace($s.tostring().substring($x,$ns.length),$ns,$x,$ns.length).tostring()