正则表达式,用于使用逗号分隔来捕获组顺序

时间:2019-08-07 11:01:43

标签: java regex

我需要与URL模式匹配的正则表达式,该URL模式以逗号分隔的任何顺序获取参数。 例如,正则表达式应匹配:

/abcd(id1='some_value',id2='some_value')

以及

/abcd(id2='some_value',id1='some_value',id2='some_value')

URL中不能有任何其他参数。每个参数应完全匹配一次。

以下正则表达式以任意顺序匹配所有参数,但它们之间没有逗号。如何在正则表达式的参数之间添加逗号?

\/abcd\((?:id='.*'()|name='.*'()|count='.*'()){3}\1\2\3\)$

2 个答案:

答案 0 :(得分:1)

  

每个参数应完全匹配一次。

是主要问题。

例如,我想出了以下正则表达式:

/abcd\s*\((?!(?:'[^']*'|[^')])*(?<=[\s(,])(name|count|id)(?=[\s=])(?:'[^']*'|[^')])*(?<=[\s,])\1(?=[\s=]))(?:(?<=[(,])\s*(?:name\s*=\s*'(?<name>[^']*?)'|count\s*=\s*'(?<count>[^']*?)'|id\s*=\s*'(?<id>[^']*?)')\s*[,)]){3}(?<=\))

它很长,所以让我们分解一下。

/<function name>\s*\(...(?<=\))

匹配函数名称function name,开头((+断言正则表达式以结尾)结尾),可选空间(我将在后面的内容中不再讨论)正则表达式)和名称前的/。请注意,java不需要转义/

(?!...)

这是检查没有多次使用参数的部分。 ...被subregex替换,如果两次使用相同的值,则该subregex将匹配。 subregex是完整正则表达式的细分形式,用于模仿匹配的名称/值对。

(?:'[^']*'|[^')])*

匹配(尽可能多地)既不是'也不是结尾)的任何字符,或者匹配一个用'分隔的 value 不包含'。这将有效地读取空格,逗号,等号和argnames和 complete 值。

(?<=[\s(,])(<argname1>|<argname2>|...)(?=[\s=])

匹配任何参数名称argname<n>。还要检查它是一个全名,而不仅仅是一个子字符串。如果名称前有逗号或空格(,则为全名。完整名称之后是空格或=。匹配的argname存储在捕获组1中。请注意,此subregex(在(?!...)内)以与 any 名称匹配的方式编写。因此,它将尝试匹配所有argname,并且仅在两次(无=否)argname被使用两次的情况下才接受。

(?:'[^']*'|[^')])*

与上述相同。匹配每个字符或完整值。

(?<=[\s,])\1(?=[\s=])

将第一个捕获组(任何argname)的内容重新匹配为完整名称(名称前为空格或逗号,名称后为空格或=)。 这是重要的部分。 是第二次使用参数名称的测试。

(?:(?<=[(,])\s*(?:...)\s*[,)]){<num arguments>}

匹配num arguments许多参数。每个参数都必须以开头的((第一个)或逗号(除了第一个以外的所有东西)开头。另外,每个参数都必须以逗号或结束)结尾。

...包含参数说明和格式的捕获组

<argname1>\s*=\s*'(?<argname1>[^']*)'|<argname2>\s*=\s*'(?<argname2>[^']*)'|...

agname<n>的值存储在具有相同名称的捕获组中。您可以使用argname作为组名从java Matcher中获取该值。以matcher.group("count")为例。

查看example

答案 1 :(得分:0)

如果要将选项之间用逗号匹配,则可以在id的值之后将()的{​​{1}}更改为,,并为结尾的参数添加一个额外的子句

此正则表达式(与您的正则表达式明显不同)将匹配括号之间的任意数量的参数,并用逗号和空格分隔

\/abcd\((id='[^']*', |name='[^']*', |count='[^']*', )*(id='[^']*'|name='[^']*'|count='[^']*')\)

在这里您可以尝试regexr.com/4iqlu

编辑:[。']替换为。*,因为我们要确保正则表达式不会在''

之外捕获