以逗号分隔捕获组排序的正则表达式

我需要匹配 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\)$


DIEA
浏览 174回答 2
2回答

回首忆惘然

每个参数应该只匹配一次。是主要问题。对于您的示例,我提出了以下正则表达式:/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、开头((+ 断言正则表达式以结尾结束))、可选空格(我不会在正则表达式的其余部分讨论)和/名称前的 a。请注意,java 不需要转义/.(?!...)这是检查没有参数被多次使用的部分。将...被一个子正则表达式替换,如果相同的值被使用两次,该子正则表达式将匹配。子正则表达式是完整正则表达式的分解形式,用于模拟匹配的名称-值对。(?:'[^']*'|[^')])*匹配(尽可能多)既不是也不是'结束符的任何字符,或者)匹配一个由 分隔且不包含的值。这将有效地读取空格、逗号、等号和 argnames 以及完整的值。''(?<=[\s(,])(<argname1>|<argname2>|...)(?=[\s=])匹配任何参数名称argname<n>。还要检查它是一个完整的名称,而不仅仅是一个子字符串。(如果名称前有空格、逗号或空缺,则这是一个完整的名称。完整名称后是空格或=. 匹配的 argname 存储在捕获组 1 中。请注意,此子正则表达式(在 中)以匹配任何(?!...)名称的方式编写。因此它将尝试匹配所有 argnames 并仅在没有(no = not any)argname 被使用两次时才接受。(?:'[^']*'|[^')])*同上。匹配每个字符或完整值。(?<=[\s,])\1(?=[\s=])将第一个捕获组(任何 argname)的内容重新匹配为完整名称(名称前的空格或逗号,=名称后的空格或逗号)。这是重要的部分。 这是第二次使用参数名称的测试。(?:(?<=[(,])\s*(?:...)\s*[,)]){<num arguments>}匹配num arguments许多参数。每个参数必须以开头((第一个)或逗号(除第一个以外的所有内容)开头。此外,每个参数必须以逗号或结束符结尾)。包含...参数规范和捕获组的形式<argname1>\s*=\s*'(?<argname1>[^']*)'|<argname2>\s*=\s*'(?<argname2>[^']*)'|...其中 for 的值agname<n>存储在具有相同名称的捕获组中。Matcher您可以使用 argname 作为组名从 java 中获取该值。举个例子matcher.group("count")。

一只甜甜圈

如果要将选项与它们之间的逗号匹配,可以在 id 的值之后更改()for ,并为结束参数添加一个额外的子句,此正则表达式(与您的略有不同)将匹配括号之间的任意数量的参数,以逗号和空格分隔\/abcd\((id='[^']*', |name='[^']*', |count='[^']*', )*(id='[^']*'|name='[^']*'|count='[^']*')\)您可以在这里试用regexr.com/4iqlu编辑:将 .* 替换为 [^']*,因为我们要确保正则表达式不会在 '' 之外捕获
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java