PowerShell正则表达式匹配Y或Z

时间:2019-03-05 16:36:17

标签: regex powershell

我正在尝试在PowerShell中使用正则表达式匹配一些字符串,但是由于我要从中提取原始字符串的格式不同,遇到了困难。我当然不擅长创建正则表达式。

我需要从每个字符串中提取数字。它们的长度可以不同,但​​是在两种情况下都将以Foo

结尾
PC1-FOO1234567
PC2-FOO1234567/FOO98765

这适用于第二个示例:

'PC2-FOO1234567/FOO98765' -match 'FOO(.*?)\/FOO(.*?)\z'

它使我可以使用$matches[1]$matches[2]访问匹配的字符串,这很棒。

对于第一个示例,它显然不起作用。我怀疑我需要某种方式在/或字符串的末尾进行匹配,但是我不确定如何执行此操作并最终得到所需的匹配。

建议?

3 个答案:

答案 0 :(得分:4)

您可以使用

match = re.search('^((.|\n)+)EXAMPLE\nTWO', file_text, flags=re.MULTILINE)
print(match.group(1))

它将匹配'FOO(.*?)(?:/FOO(.*))?$' ,然后将尽可能少的0个或多个字符捕获到组1中,然后尝试有选择地匹配一系列模式:FOO,将0个或多个字符作为尽可能多地捕获到第2组中,然后应该跟随字符串结尾的位置。

请参见regex demo

详细信息

  • /FOO-文字子字符串
  • FOO-第1组:除换行符外的任何零个或多个字符,请尽可能少
  • (.*?)-一个与以下项的1或0次重复匹配的可选非捕获组:
    • (?:/FOO(.*))?-文字子字符串
    • /FOO-第2组:尽可能多的除换行符外的0+个字符((.*)是贪婪的)
  • *-字符串的结尾。

enter image description here

答案 1 :(得分:2)

[edit-删除了不需要的管道到Where-Object。感谢mklement0! [*咧嘴*]]

这是有点不同的方法。它在foo上分割,然后将多余的/用任何内容替换,最后过滤掉包含字母的任何字符串。

其他人提供的纯正则表达式解决方案可能会更快,但这可能更易于理解-因此易于维护。 [咧嘴]

# fake reading in a text file
#    in real life, use Get-Content
$InStuff = @'
PC1-FOO1234567
PC2-FOO1234567/FOO98765
'@ -split [environment]::NewLine

$InStuff -split 'foo' -replace '/' -notmatch '[a-z]'

输出...

1234567
1234567
98765

答案 2 :(得分:2)

要为-split运算符提供更简洁的替代方法,这样就无需再访问$Matches来提取数字:

PS> 'PC1-FOO1234568', 'PC2-FOO1234567/FOO98765' -split '(?:^PC\d+-|/)FOO' -ne ''
1234568  # single match from 1st input string
1234567  # first of 2 matches from 2nd input string
98765

注意:-split始终返回[string[]]数组,即使仅返回1个字符串也是如此;来自多个输入字符串的结果字符串被组合成一个单一的平面数组。

  • ^PC\d+-|/匹配PC,后跟字符串(+开头的1个或多个(\d)数字(^|)一个/字符,它与开头的PC2-FOO/FOO都匹配。

    • (?:...)不可捕获的子表达式,必须用于防止-split在结果数组中包括与该子表达式匹配的子项。
  • -ne ''过滤掉元素,这些元素是由输入字符串开始并带有分隔符而产生的。


要了解有关基于正则表达式的-split运算符以及它在哪些方面比基于字符串文字的.NET String.Split()方法更强大的信息,请参见this answer