我想使用RegEx以便从产品名称中删除版本号。名称看起来像这样:
SampleProduct 2.0
它们也可以在版本号前后加上括号:
SampleProduct (2.1)
因此,我尝试为版本号定义一个组,并为使用括号的版本定义一个替代项:
\s((?<versionNumber>\d+(\.\d+)*)|\(\k<versionNumber>\))\z
但这不会产生匹配。由于模式很小,因此我尝试使用索引访问该组:
\s((\d+(\.\d+)*)|\(\2\))\z
这也不起作用。顺便说一下,嵌套组的索引顺序是什么?它们是否按开括号或闭括号的顺序排序?无论如何,\1
,\2
和\3
都没有匹配。
我试图找出我是否误解了正则表达式的功能。当我分别尝试分组和替代时,它们按预期方式工作。但是,当我混合使用这两个功能时,有时它会停止工作,并且我无法发现问题。 目前,我已成功使用表达式而不进行分组来删除版本:
name = name.Substring(0, name.Length - Regex.Match(name, @"\s(\d+(\.\d+)*|\(\d+(\.\d+)*\))\z").Value.Length);
但是我想避免模式重复。
答案 0 :(得分:1)
如果要避免在正则表达式中重复模式的一部分,而只想匹配2.0
或(2.0)
而不是(2.0
或2.0)
,则可以使用条件正则表达式:
(\()?\d+(?:\.\d+)*(?(1)\))
请参见regex demo。
如果只有一个括号,则不会成为匹配项。
详细信息
(\()?
-一个可选的捕获组#1:(
字符(如果没有(
,则该组的值为 null ,并且以后(?(1)...)
检查将失败)\d+
-1个或更多数字(?:\.\d+)*
-重复.
和1个以上数字0个或更多(?(1)\))
-一种条件构造:如果第1组匹配,则)
必须匹配,否则就没有匹配项(|...)
缺少条件部分意味着任何事物都可以遵循该模式)。