使用PowerShell,但对其他可能的解决方案开放......
我有一个很长的字符串。我需要通过掩码字符(句点或空格)在该字符串中的位置替换几个字符序列。我不知道那些角色会是什么,但我知道他们需要成为别的东西。我使用mid编写代码并使用mid和position数字迭代字符串,但这有点麻烦,并且想知道是否有更快/更优雅的方法。
实施例: 鉴于2个字符串:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
12345678901234567890123456
我想替换字符2-4,8-9,16-22和& 23 with。,屈服:
A...EFGH..KLMNOP.....VWX.Z
1...5678..123456.....234.6
我可以用一系列MID来做到这一点,但我只是想知道是否有某种更快的屏蔽功能来实现这一点。我必须通过数百万行和第二次计数来做到这一点。
答案 0 :(得分:3)
试试这个:
$regex = [regex]'(.).{3}(.{4}).{2}(.{6}).{5}(.{3}).(.+)'
$replace = '$1...$2..$3.....$4.$5'
('ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'12345678901234567890123456') -Replace $regex,$replace
A...EFGH..KLMNOP.....VWX.Z
1...5678..123456.....234.6
对于单个操作,-replace运算符比string.replace()慢,但是具有能够对字符串数组进行操作的优点,这比字符串方法加上foreach循环更快。
这是一个示例实现(需要V4):
$regex = [regex]'(.).{3}(.{4}).{2}(.{6}).{5}(.{3}).(.+)'
$replace = '$1...$2..$3.....$4.$5'
filter fix-file {
$_ -replace $regex,$replace |
add-content "c:\mynewfiles\$($file.name)"
}
get-childitem c:\myfiles\*.txt -PipelineVariable file |
get-content -ReadCount 1000 | fix-file
如果你想使用mask方法,可以从中生成$ regex和$ replace:
$mask = '-...----..------.....---.-'
$regex = [regex]($mask -replace '(-+)','($1)').replace('-','.')
$replace =
([char[]]($mask -replace '-+','-') |
foreach {$i=1}{if ($_ -eq '.'){$_} else {'$'+$i++}} {}) -join ''
$regex.ToString()
$replace
(.)...(....)..(......).....(...).(.)
$1...$2..$3.....$4.$5
答案 1 :(得分:2)
这是另一种方法:
C:\PS> $mask ="-...----..------.....---.-"
C:\PS> ([char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | % {$i=0}{if ($mask[$i++] -eq '-') {$_} else {'.'}}) -join ''
A...EFGH..KLMNOP.....VWX.Z
如果我们要利用V4功能:-),试试这个:
C:\PS> $i=0;([char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ').Foreach({if ($mask[$i++] -eq '-') {$_} else {'.'}}) -join ''
答案 2 :(得分:2)
这是另一种方法:
C:\PS> $mask = "{0}...{4}{5}{6}{7}..{10}{11}{12}{13}{14}{15}.....{21}{22}{23}.{25}"
C:\PS> $singlecharstrings = [string[]][char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
C:\PS> $mask -f $singlecharstrings
A...EFGH..KLMNOP.....VWX.Z