我正在尝试在PowerShell中使用正则表达式匹配一些字符串,但是由于我要从中提取原始字符串的格式不同,遇到了困难。我当然不擅长创建正则表达式。
我需要从每个字符串中提取数字。它们的长度可以不同,但是在两种情况下都将以Foo
PC1-FOO1234567
PC2-FOO1234567/FOO98765
这适用于第二个示例:
'PC2-FOO1234567/FOO98765' -match 'FOO(.*?)\/FOO(.*?)\z'
它使我可以使用$matches[1]
和$matches[2]
访问匹配的字符串,这很棒。
对于第一个示例,它显然不起作用。我怀疑我需要某种方式在/
或字符串的末尾进行匹配,但是我不确定如何执行此操作并最终得到所需的匹配。
建议?
答案 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+个字符((.*)
是贪婪的)*
-字符串的结尾。答案 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。