如果这是一个非常简单的问题我很抱歉。我第一次在Powershell中使用正则表达式...
在$ string中,我试图淘汰第一个" -1"所以字符串的输出将是"测试测试test-Long.xml"。
$string = 'test test test-1-Long.xml'
$string -replace '^(.*)-?\d?(-?.*)\.xml$', '$1$2'
我的问题是我需要先做同样的事情" -1"模式可选,因为连字符和数字都不能存在。
为什么" ?
"操作员不工作?我也在每次尝试{0,1}
之后也没有运气。这必须是显而易见的......
答案 0 :(得分:1)
正则表达式是贪婪的,所以引擎无法决定匹配什么,这是不明确的。
不确定这是最好的解决方案,但我可以这样做:
$string -replace '^([^\-]*)-?\d?(-?.*)\.xml$', '$1$2'
唯一的变化:第一组不得包含破折号:那种“平衡”正则表达式,避免贪婪并产生:
test test test-Long
注意:答案中的输出不是test test test-Long.xml
。为此,只需删除xml后缀:
$string -replace '^([^\-]*)-?\d?(-?.*)', '$1$2'
答案 1 :(得分:0)
如果输入中必须使用连字符,则$string -replace '^(.*?)(?:-\d+)?(-.*?)\.xml$', '$1$2'
应该有效。或$string -replace '^((?:(?!-\d+).)*)(?:-\d+)?(.*)\.xml$', '$1$2'
以防输入可能没有连字符。
模式详情:
^
- 字符串开头(.*?)
- 第1组捕获除换行符之外的任何0 +字符尽可能少(因为*?
量词是 lazy )直到第一个(注意:为了提高正则表达式的性能,您可以使用基于驯化贪婪令牌的模式而不是(.*?)
- ((?:(?!-\d+).)*)
来匹配除-
+ 1 or more digits
以外的任何文字因此,类似于否定的字符类,但对于一系列符号)(?:-\d+)?
- 具有贪婪?
量词的非捕获组(因此,此组具有更高优先级的正则表达式引擎,之前的捕获将在此模式之前结束)捕获连字符后跟1或更多数字(-.*?)
- 第3组捕获强制性-
和除LF以外的任何0+字符,尽可能少\.xml
- 文字.xml
$
- 字符串结束。为什么"?"操作员不工作?
不是这样,量词?
运行良好,因为它匹配量化子模式的一个或零次出现。但是,问题出现在第一个.*
贪婪点匹配子模式的组合中。请参阅your regex in action:第一个捕获组抓取整个子字符串直到最后.xml
,第二个组为空。为什么呢?
由于回溯以及量词的贪婪程度如何。 .*
匹配任何字符,但新行尽可能多。因此,它将整个字符串抓到最后。然后,开始回溯:一次返回一个char并对后续的子模式进行测试。这些是什么? -?\d?(-?.*)
- 所有这些都可以匹配一个空字符串。 -?
在.xml
之前匹配空字符串,ok,\d?
也匹配,-?
和.*
也匹配。但是,.*
再次抓取整个字符串,但可以容纳\.xml
模式。所以,第二个捕获组只是空的。事实上,正则表达式引擎执行的步骤更多(参见regex debugger页面),但主要思想就是这样。