【问题标题】:Powershell Replace Characters in a StringPowershell 替换字符串中的字符
【发布时间】:2013-12-08 01:14:51
【问题描述】:

使用 powershell,但对其他潜在解决方案持开放态度....

我有一个很长的字符串。我需要用掩码字符(句点或空格)按该字符串中的位置替换几个字符序列。我不知道这些角色会是什么,但我知道他们需要是别的东西。我已经使用 mid 编写代码并使用 mid 和 position 数字遍历字符串,但这有点麻烦,想知道是否有更快/更优雅的方法。

示例: 给定 2 个字符串:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
12345678901234567890123456

我想用 . 替换字符 2-4、8-9、16-22 和 23,得到:

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

我可以使用一系列 MID 来做到这一点,但我只是想知道是否有某种更快的屏蔽功能来实现这一点。我必须通过数百万行和秒数来做到这一点。

【问题讨论】:

    标签: string powershell replace position


    【解决方案1】:

    试试这个:

    $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() 慢,但优点是可以对字符串数组进行操作,比 string 方法加 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
    

    【讨论】:

      【解决方案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 ''
      

      【讨论】:

      • 天哪,这似乎过于复杂了。顺便说一句,您还可以使用以下内容创建一个包含 A 到 Z 的 char 数组:[char[]]([char]'A'..[char]'Z')
      • 真的很喜欢显式掩码。使用字符串格式对此进行了修改。
      • 是的,我不认为它那么复杂。一个简单的循环遍历每个字符并测试是否掩码似乎更像 CS 101。:-)
      【解决方案3】:

      这里还有另一种方法:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-20
        • 2017-03-06
        • 2013-02-01
        • 2021-12-19
        • 2021-10-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多