Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex Powershell中的可选正则表达式运算符_Regex_Powershell - Fatal编程技术网

Regex Powershell中的可选正则表达式运算符

Regex Powershell中的可选正则表达式运算符,regex,powershell,Regex,Powershell,在$string中,我试图逐步淘汰第一个“-1”,因此字符串的输出将是“test Long.xml” 我的问题是,我需要使相同的第一个“-1”模式成为可选模式,因为连字符和数字不能同时出现 为什么“?”操作员不工作?我也在每次之后都尝试了{0,1},但没有运气。正则表达式是贪婪的,因此引擎无法决定匹配什么,这是不明确的 不确定这是不是最好的解决方案,但我可以这样做: $string -replace '^([^\-]*)-?\d?(-?.*)\.xml$', '$1$2' 唯一的变化:第一组不

在$string中,我试图逐步淘汰第一个“-1”,因此字符串的输出将是“test Long.xml”

我的问题是,我需要使相同的第一个“-1”模式成为可选模式,因为连字符和数字不能同时出现


为什么“
”操作员不工作?我也在每次之后都尝试了
{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'