我需要与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\)$
答案 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
编辑:[。']替换为。*,因为我们要确保正则表达式不会在''
之外捕获