Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Powershell在位置x处替换字符_String_Performance_Powershell_Replace - Fatal编程技术网

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()