PowerShell删除正则表达式中的点

时间:2016-03-15 13:10:21

标签: regex powershell

我在powershell中有以下单行:

cat raw.txt | select-string -Pattern "\A[s]\w{1,12}\.\b" -AllMatches | % { $_.Matches } | % { $_.Value }

返回:

saltri.
swoptimusprime.
swdecepticons.

问题 如何删除点"。"来自我的主机名

提前致谢

2 个答案:

答案 0 :(得分:1)

PetSerAl,在对该问题的评论中,提供了关键指针:使用positive lookahead assertion ((?=...))来匹配输入的其他部分,而不在捕获的匹配中包含该部分

如果我们将此应用于您的解决方案并简化它,我们会得到:

Get-Content raw.txt | % { if ($_ -match '^s\w{1,12}(?=\.\b)') { $matches[0] } }

子表达式\.\b - 文字.后跟(非捕获)过渡到单词字符\b - 匹配,但不是捕获;也就是说,$matches[0]是包含字符串匹配部分的特殊$matches变量的元素,包含.

但是,由于我们之后使用-match并访问特殊的$matches变量,我们可以简化正则表达式中捕获组((...))的问题我们可以通过索引1访问子字符串,因为它是正则表达式中的第一个(且唯一)捕获组:

Get-Content raw.txt | % { if ($_ -match '^(s\w{1,12})\.\b') { $matches[1] } }

有关您的解决方案尝试的说明(除了在匹配中包含.):

  • 您在没有切换Get-Content的情况下使用-Raw,这意味着输入行将通过管道单独发送

    • 因此,没有理由使用\A代替更熟悉的字符串/行首字母^,因为这两者仅与多行不同输入。
    • 由于您在该行的开头处锚定了匹配项,因此-AllMatches选项毫无意义,因为根据定义,每行最多只能有 1 匹配。< / LI>
  • 正如您所看到的,在这种情况下,只有% ForEach-Object-match块就足够了,简化了问题;在这种情况下,它都返回不需要的信息,并且性能优于Select-String

答案 1 :(得分:0)

由于我不知道你的文字是怎样的,所以对主机名进行分组应该足够了(通过-match进行较短的尝试):

cat raw.txt | % {$_ -match "\A([s]\w{1,12})\.\b"; $matches[1] }