.net 当试图使某些部分成为可选部分时,会弄乱正则表达式
今天我一直在尝试使用正则表达式解析命令 我有几次接近于一个解决方案,但总有一点把事情搞砸了 我试图保持表达式的通用性,因为我希望在不同的命令上使用它,尽管参数的数量是相同的 我基本上最多有4个捕获组:.net 当试图使某些部分成为可选部分时,会弄乱正则表达式,.net,regex,.net,Regex,今天我一直在尝试使用正则表达式解析命令 我有几次接近于一个解决方案,但总有一点把事情搞砸了 我试图保持表达式的通用性,因为我希望在不同的命令上使用它,尽管参数的数量是相同的 我基本上最多有4个捕获组: 1号(单块,无空格) 数字2(单块,无空格,可选) 参数1 参数2(可选) Number1和Number2由'-'分隔(=可选,无'-'无编号2) Number1(+Number2)和Param1之间用空格(=必填)分隔 Param1和Param2由空格分隔(=可选) 因此,命令的基本布局是: [
Number1(+Number2)和Param1之间用空格(=必填)分隔
Param1和Param2由空格分隔(=可选) 因此,命令的基本布局是: [Number1]-[Number2][Param1][Param2] 以下是可以预期的示例输入列表: 123456A789C试验
- 编号1=123456A789C
- Number2=未捕获
- 参数1=测试
- Param2=未捕获
- Number1=123456.789C
- 数字2=987654Z321Y
- 参数1=测试
- Param2=未捕获
- Number1=123456.789C
- Number2=未捕获
- 参数1=test1
- 参数2=test2
- Number1=123456.789C
- 数字2=987654Z321Y
- 参数1=test1
- 参数2=test2
1-2“test1 test2”test2“test2 test3”不能作为1-2 test1 test2 test3 test4输入
(?i)^(?<numbers>(?<number1>.*)-(?<number2>.*))\s(?<params>"(?<param1>[^"]*)"\s"(?<param2>[^"]*)")$
输入示例:
123456.789C-987654Z321Y“测试1测试2”测试3测试4
- Number1=123456.789C
- 数字2=987654Z321Y
- Param1=test1test2(注意如何不捕获引号)
- Param2=test3test4(注意引号是如何被捕获的)
(?i)^(?<numbers>(?<number1>[^\s]*?)(?:[-](?<number2>[^\s]*?))?)\s(?<params>("?)(?<param1>[^"]*)\1\s("?)(?<param2>[^"]*)\2)$
(?i)^(?(?[^\s]*?)(?:[-](?[^\s]*?)?)\s(?(“?)(?[^”]*)\1\s(“?)(?[^”]*)\2)$
但是,它不接受1测试,1-2测试,1测试,1-2测试,1测试,1-2测试
一些正则表达式专业人士能帮我解释一下我的表达式哪里出了问题吗
下面是另一个正则表达式,我使用它作为匹配最完整命令的起点,例如1-2“test1 test2”“test3 test4”
(?i)^(?(?.*)-(?.*)\s(?(?[^]*)“\s”(?[^]*))$
(?[^-]+)((?[^]+)(?(“[^”]+”)([^]+)(((?(“[^”]+”))(((?(“[^]+”))))?
为了清晰起见,我从示例中删除了所有命名组 我想到了这个
<!-- language: none -->
^([a-zA-Z0-9.]+)(-([a-zA-Z0-9.]+))?\s(([a-zA-Z][a-zA-Z0-9]*)|"[a-zA-Z 0-9]+")(\s(([a-zA-Z][a-zA-Z0-9]*)|"[a-zA-Z 0-9]+"))?
^([a-zA-Z0-9.]+)([a-zA-Z0-9.]+)?\s([a-zA-Z][a-zA-Z0-9]*)|“[a-zA-Z 0-9]+”)([a-zA-Z][a-zA-Z0-9]*)|“[a-zA-Z 0-9]+”)?
(见附件)
这是一个细分
- 我们从一行的开头开始(确保您使用的函数可以产生所需的选项:不区分大小写、全局匹配、多行。我在正则表达式引擎上使用了该选项以简化)
- 然后,我们希望捕获一个或两个编号
,用于强制性的第一个编号,以及([a-zA-Z0-9.]+)
,用于可选的第二个编号([a-zA-Z0-9.]+)?
- 我们添加了一个空格
。请注意,这不能像您那样在\s
中使用,因为他们将速记还原为其字面意思反斜杠或s[]
- 然后我们要匹配一个标识符,该标识符有或没有双引号
注意这一点。替换的第二部分添加了([a-zA-Z][a-zA-Z0-9]*)|“[a-zA-Z 0-9]+”)
和”
- 第二个是可选的,但如果存在
(\s(([a-zA-Z][a-zA-Z0-9]*)|“[a-zA-Z 0-9]+”)则以空格开头)
- 我们可以以
$
(?im)^([a-zA-Z0-9.]+)([a-zA-Z0-9.]+)?\s([a-zA-Z0-9]*|“[a-zA-Z0-9]+”)(\s([a-zA-Z0-9]*|“)$
你自己看看:你的解释和表达让它看起来很明显,我现在觉得很愚蠢--这个表达完全符合我所有的测试用例。这个图表也很有说明性!在一些初始测试之后,我不明白为什么当我添加“^”和“$”以便在整个字符串上进行匹配时,这个表达式将不起作用。。。另一方面,它还匹配参数周围的引号(如果有)
<!-- language: none -->
^([a-zA-Z0-9.]+)(-([a-zA-Z0-9.]+))?\s(([a-zA-Z][a-zA-Z0-9]*)|"[a-zA-Z 0-9]+")(\s(([a-zA-Z][a-zA-Z0-9]*)|"[a-zA-Z 0-9]+"))?