【问题标题】:Redacting capture group values编辑捕获组值
【发布时间】:2019-12-26 07:17:34
【问题描述】:

使用 REGEX 在捕获组中查找模式;现在我需要替换/编辑找到的值。

尝试替换固定长度字段中的值:
正则表达式搜索:(\d{10})(.{20}) (.+)

字符串是:

01234567890Alice Stone          3978 Smith st...

我必须用 X 替换捕获组 2(全名)(或者更好的是仅捕获组 2 中的名字和姓氏)

正则表达式:(\d{10})(.{20})(.+)

替换值$1xxxxxxxxxxxxxxxxxxxx$3

这行得通,但认为会有一个更迷人的解决方案(可能像$1 x{20} $3),或者甚至更好地以某种方式使用其中的字母来编辑值。

谢谢!

【问题讨论】:

    标签: regex powershell redaction


    【解决方案1】:

    为了制定一个替换字符串,其长度应该匹配输入字符串的一个 - 潜在可变长度 - 子字符串,您需要通过 脚本块动态地 计算替换字符串(代表)。

    在 PowerShell Core 中,您现在可以直接将脚本块作为 -replace operator 的替换操作数传递:

    PS> '01234567890Alice Stone          3978 Smith st...' -replace 
          '(?<=^\d{10}).{20}', { 'x' * $_.Value.Length }
    
    0123456789xxxxxxxxxxxxxxxxxxxx  3978 Smith st...
    
    • '(?&lt;=^\d{10} 是一个正向的后向断言,它匹配前 10 个数字而不捕获它们,.{20} 匹配并捕获接下来的 20 个字符。

    • 每次匹配都会调用脚本块,$_ 包含手头的匹配作为 [System.Text.RegularExpressions.Match] 实例; .Value 包含匹配的文本。

    • 因此,'x' * $_.Value.Length 返回一个由 x 字符组成的字符串。与匹配的长度相同。


    Windows PowerShell 中,您必须直接使用 [regex] type

    PS> [regex]::Replace('01234567890Alice Stone          3978 Smith st...',
          '(?<=^\d{10}).{20}', { param($m) 'x' * $m.Value.Length })
    
    0123456789xxxxxxxxxxxxxxxxxxxx  3978 Smith st...
    

    如果要替换的子字符串的长度是提前知道的 - 就像你的情况一样 - 你可以更简单地做:

    
    PS> $len = 20; '01234567890Alice Stone          3978 Smith st...' -replace 
          "(?<=^\d{10}).{$len}", ('x' * $len)
    
    0123456789xxxxxxxxxxxxxxxxxxxx  3978 Smith st...
    

    无条件地编辑所有字母更加简单:

    PS> '01234567890Alice Stone          3978 Smith st...' -replace '\p{L}', 'x'
    
    01234567890xxxxx xxxxx          3978 xxxxx xx...
    

    \p{L} 匹配任何 Unicode 字母。


    仅在匹配的子字符串中编辑字母需要嵌套 -replace 操作:

    PS> '01234567890Alice Stone          3978 Smith st...' -replace 
          '(?<=^\d{10}).{20}', { $_ -replace '\p{L}', 'x' }
    
    01234567890xxxxx xxxxx          3978 Smith st...
    

    【讨论】:

      【解决方案2】:

      也许,这个表达式是一个选项:

      ([0-9]{11}).+?(\s*[0-9].+)
      

      替换为:

      $1xxxxxxxxxxxxxxxxxxxx$2
      

      如果您想探索/简化/修改表达式,它已经 在右上角的面板上进行了解释 regex101.com。如果你愿意,你 也可以在this link看,怎么搭配 针对一些样本输入。


      【讨论】:

        【解决方案3】:

        你可以用这个:

        $oldstr = "0123456789Alice Stone 3978 Smith st..."
        [regex]$r = '(\d{10})(.{20})(.+)'
        
        $newstr = $r.Replace($data,'$1'+'x'*20+'$3')
        

        这里,“x”字符乘以 20(有效重复 20 次)。

        0123456789xxxxxxxxxxxxxxxxxxxxth st...

        正如其他人所展示的,捕获组 2 不是必需的,因此可以简化为:

        [regex]$r = '(\d{10}).{20}(.+)'
        
        $newstr = $r.Replace($data,'$1'+'x'*20+'$2')
        

        【讨论】:

          猜你喜欢
          • 2014-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-30
          • 1970-01-01
          • 2012-06-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多