在 .NET 中使用带可选参数的正则表达式匹配重复组

Match repeating groups with regex with optional parameter in .NET

我需要使用正则表达式验证过滤输入,该正则表达式将用于 class 使用的输入模型中 Filter 字段的 [RegularExpression] 属性。输入格式如下:

[property]~[predicate]~[value]

例如:

lastname~eq~'John'

也可以多次过滤n次:

[property]~[predicate]~[value]~[logicaloperator]~[property]~[predicate]~[value] ...

例如:

lastname~eq~'Doe'~and~firstname~eq~'John'~or~firstname~eq~'Jane'

我必须确保如果使用了逻辑运算符,那么它们后面会有相同的模式。我尝试使用命名组和回顾但无法正常工作。

我创建了以下正则表达式:

((((\w+)~(\blt\b|\blte\b|\beq\b|\bgt\b|\bgte\b|\bneq\b|\bcontains\b)~(.\w+.))(~(\bor\b|\band\b)~)?((\w+)~(\blt\b|\blte\b|\beq\b|\bgt\b|\bgte\b|\bneq\b|\bcontains\b)~(.\w+.))?)+)

我无法让它仅在输入有效时匹配。我尝试实现的组的一般模式是:

(main group-
 (property group-any word)~(predicate group-list of operators)~(value -any value)
)
(~(logic operator)~)
(main group)

目标行为:

有效输入:

lastname~eq~'Doe'                                                      -> should match
lastname~eq~'Doe'~and~firstname~eq~'John'                              -> should match
lastname~eq~'Doe'~and~firstname~eq~'John'~or~firstname~eq~'Jane'        -> should match

输入无效:

lastname~eq~                                          ->should not match
lastname~eq~'Doe'~and~firstname~eq                    ->should not match
lastname~eq~'Doe'~and~firstname~eq~John~              ->should not match
lastname~eq~'Doe'~and~firstname~eq~John~or~           ->should not match

关于如何使这项工作有任何想法吗?

您可以使用

^\w+~(?:lte?|n?eq|gte?|contains)~['"][^'"]+['"](?:~(?:and|or)~\w+~(?:lte?|n?eq|gte?|contains)~['"][^'"]+['"])*$

或者,

^(?:\w+~(?:lte?|n?eq|gte?|contains)~['"][^'"]+['"](?:~(?:and|or)~(?!$)|$))+$

参见regex demo

请注意,在正则表达式演示中,$ 前面有 \r?,因为该字符串是一个带有 CRLF 行结尾的多行字符串,并且启用了 RegexOptions.Multiline 选项。

模式匹配

  • ^ - 字符串开头
  • \w+ - 一个或多个单词字符
  • ~ - 一个 ~ 字符
  • (?:lte?|n?eq|gte?|contains) - 谓词模式(ltltegtgteneqeq , contains
  • ~ - 一个 ~ 字符
  • ['"][^'"]+['"] - '",然后是 '" 以外的一个或多个字符,然后是 "'
  • (?: - non-capturing 组的开始
    • ~(?:and|or)~ - ~andor,以及一个 ~ 字符
    • \w+~(?:lte?|n?eq|gte?|contains)~['"][^'"]+['"] - 如上所述
  • )* - 零次或多次重复
  • $ - 字符串结尾。