简体   繁体   English

Powershell替换字符串中的字符

[英]Powershell Replace Characters in a String

Using powershell, but open to other potential solutions.... 使用PowerShell,但对其他潜在的解决方案开放....

I have a long string. 我有一根长串。 I need to replace several sequences of characters by position in that string with a mask character (period or space). 我需要用掩码字符(句点或空格)在该字符串中的位置替换几个字符序列。 I don't know what those characters are going to be, but I know they need to be something else. 我不知道那些角色会是什么,但我知道他们需要成为别的东西。 I have written code using mid and iterating through the string using mid and position numbers, but that is a bit cumbersome and wondering if there is a faster/more elegant method. 我已经使用mid编写了代码,并使用mid和position数字遍历了字符串,但这有点麻烦,想知道是否有一种更快/更优雅的方法。

Example: Given the 2 strings: 示例:给出2个字符串:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
12345678901234567890123456

I want to replace characters 2-4, 8-9, 16-22, & 23 with ., yielding: 我想用。替换字符2-4,8-​​9,16-22和23,产生:

A...EFGH..KLMNOP.....VWX.Z
1...5678..123456.....234.6

I can do that with a series of MID's, but I was just wanting to know if there were some sort of faster masking function to make this happen. 我可以使用一系列MID来做到这一点,但是我只是想知道是否存在某种更快的屏蔽功能来实现这一目标。 I have to do this through millions of rows and second count. 我必须通过数百万行和第二次计数来做到这一点。

Try this: 尝试这个:

$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

The -replace operator is slower than string.replace() for a single operation, but has the advantage of being able to operate on an array of strings, which is faster than the string method plus a foreach loop. 对于单个操作,-replace运算符比string.replace()慢,但是具有能够对字符串数组进行操作的优点,这比字符串方法加上foreach循环更快。

Here's a sample implementation (requires V4): 这是一个示例实现(需要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 

If you want to use the mask method, you can generate $regex and $replace from that: 如果要使用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

Here another approach: 这里是另一种方法:

C:\PS> $mask ="-...----..------.....---.-"
C:\PS> ([char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | % {$i=0}{if ($mask[$i++] -eq '-') {$_} else {'.'}}) -join ''

A...EFGH..KLMNOP.....VWX.Z

And if we are going to take advantage of V4 features :-), try this: 如果我们要利用V4功能:-),请尝试以下操作:

C:\PS> $i=0;([char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ').Foreach({if ($mask[$i++] -eq '-') {$_} else {'.'}}) -join ''

Here yet another approach: 这是另一种方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM