Regex Powershell中的可选正则表达式运算符
在$string中,我试图逐步淘汰第一个“-1”,因此字符串的输出将是“test Long.xml” 我的问题是,我需要使相同的第一个“-1”模式成为可选模式,因为连字符和数字不能同时出现Regex Powershell中的可选正则表达式运算符,regex,powershell,Regex,Powershell,在$string中,我试图逐步淘汰第一个“-1”,因此字符串的输出将是“test Long.xml” 我的问题是,我需要使相同的第一个“-1”模式成为可选模式,因为连字符和数字不能同时出现 为什么“?”操作员不工作?我也在每次之后都尝试了{0,1},但没有运气。正则表达式是贪婪的,因此引擎无法决定匹配什么,这是不明确的 不确定这是不是最好的解决方案,但我可以这样做: $string -replace '^([^\-]*)-?\d?(-?.*)\.xml$', '$1$2' 唯一的变化:第一组不
为什么“
?
”操作员不工作?我也在每次之后都尝试了{0,1}
,但没有运气。正则表达式是贪婪的,因此引擎无法决定匹配什么,这是不明确的
不确定这是不是最好的解决方案,但我可以这样做:
$string -replace '^([^\-]*)-?\d?(-?.*)\.xml$', '$1$2'
唯一的变化:第一组不能包含破折号:这种“平衡”正则表达式,避免贪婪,产生:
test test test-Long
注意:输出不是回答中要求的test Long.xml
。为此,只需删除xml后缀:
$string -replace '^([^\-]*)-?\d?(-?.*)', '$1$2'
如果输入中必须使用连字符,
$string-replace'^(.*?(:-\d+)(.*?\.xml$”、“$1$2”
,则应可以使用。或$string-replace'^((?:(?!-\d+)*)(?:-\d+)(.*)\.xml$,“$1$2”
,以防输入可能没有连字符
请参阅和
图案细节:
-字符串的开头^
-第1组捕获除换行符以外的任何0+字符(因为(.*)
量词是惰性的),直到第一个(注意::为了提高正则表达式的性能,您可以使用基于标记的模式,而不是*?
-(.*)
匹配任何文本,但不匹配((?:(?!-\d+)*)
+-
,因此,其作用类似于求反字符类,但用于符号序列)1个或多个数字
-带有贪婪的(?:-\d+)
量词的非捕获组(因此,此组对正则表达式引擎具有更高的优先级,上一次捕获将在此模式之前结束)捕获一个连字符,后跟一个或多个数字?
-第3组捕获强制(.*?)
和除LF以外的任何0+字符,尽可能少到-
-文本\.xml
.xml
-字符串结束$
?
工作良好,因为它匹配量化子模式的一次或零次出现。但是,该问题与第一个贪心点匹配子模式一起出现。请参阅:第一个捕获组捕获到最后一个.xml
的整个子字符串,第二个组为空。为什么?
因为回溯和贪婪量词的工作原理。
*
尽可能多地匹配除换行符以外的任何字符。因此,它抓住了整个字符串直到结束。然后,开始回溯:一次返回一个字符,并针对后续子模式进行测试。它们是什么<代码>-?\d?(?*)-所有这些都可以匹配一个空字符串。-?
匹配.xml
之前的空字符串,好的,\d?
也匹配那里,-?
和*
也匹配那里。但是,*
再次抓取整个字符串,但是有\.xml
模式可以容纳。因此,第二个捕获组是空的。事实上,正则表达式引擎执行的步骤还有很多(请参见页面),但主要思想是这样的。这对于“test-1-Long.xml”非常有效,但是对于“test-Long.xml”的输入,它返回“test-Long.xml”,第一个连字符、第一个数字和第二个连字符都需要是可选的。在test-test--Long.xml
或test-1Long.xml
的情况下,这会做错误的事情。-1
可以位于可选的非捕获组中,但是:(?:-\d)?
@Laterade:您希望testLong.xml
还是testLong.xml
?我是confused@PaulHicks:您的技巧更好,但如果用户输入,我将使用您的代码或我的蹩脚代码获得testlong.xml
。仍然不清楚OP想要什么…正则表达式是贪婪的声明是错误的。这里有一个贪婪的子模式,它是罪魁祸首。但是,没有给出解释。为什么$string-replace'^(.*)-\d+\b(.*)\.xml$'、'$1$2'
不能按预期工作?您不需要任何可选组。请注意,当不存在匹配项时,replace
将返回未更改的字符串。
$string -replace '^([^\-]*)-?\d?(-?.*)', '$1$2'