单独的正则表达式子句
Separate regex clauses
我需要将字符串与预定义关键字列表进行匹配,并将其捕获到一个组中,因为关键字前面可能有一个可选字符。
例子
允许的关键字:
- 包含[=36=]
- 开始于
- 等于
- 结束于
可选字符:!
- input value - comment
contains(field,value) // OK
startswith(field,value) // OK
test(field,value) // NOK (test is not a valid keyword)
equals(field,value) // OK
!startswith(field,value) // OK (optional character ! allowed)
!contains(field,value) // OK (optional character ! allowed)
正则表达式
我尝试使用以下正则表达式:
(?<action>!?startswith|endswith|contains|equals)\((?<field>\w+),(?<value>\w+)\)
我可以成功捕获组(action
、field
、value
),但正则表达式只允许 startswith
的可选字符。我怎样才能分开这两个规则并仍然捕获完整的关键字?像 capture=(optional ?)(any of the allowed keywords)
只需将 !?
放在捕获组之外。
@"!?\b(?<action>startswith|endswith|contains|equals)\((?<field>\w+),(?<value>\w+)\)"
\b
!?
之后的单词边界是非常需要的。
如果要捕获 !startswith 和 !contains,请使用以下命令...
(?<action>!?(startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)
为什么不用
(?<=^|\p{P}|\p{Zs}|\b)(?<action>\!?(?:startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)(?=$|\p{P}|\p{Zs}|\b)
?
你将匹配几乎所有可能的边界+“!?”仅在 ?<action>
组内使用一次,您的操作将保留带有或不带 !
符号的方法名称。
下面是一些测试代码:
var MyRegex = new Regex(
"(?<=^|\p{P}|\p{Zs}|\b)(?<action>\!?(?:startswith|endswit" +
"h|contains|equals))\((?<field>\w+),(?<value>\w+)\)(?=$|\p" +
"{P}|\p{Zs}|\b)",
RegexOptions.IgnoreCase
| RegexOptions.Multiline
| RegexOptions.CultureInvariant
| RegexOptions.Compiled
);
// Capture all Matches in the InputText
var ms = MyRegex.Matches(@"contains(field,value) OK
startswith(field,value) OK
test(field,value) NOK (test is not a valid keyword)
equals(field,value) OK
!startswith(field,value) OK (optional character ! allowed)
!contains(field,value) OK (optional character ! allowed)");
foreach (var capturedgroup in ms.Cast<Match>().ToList())
{
var action = capturedgroup.Groups["action"].Value;
var field = capturedgroup.Groups["field"].Value;
var value = capturedgroup.Groups["value"].Value;
}
或者,如果您必须将方法名称检查为单独的字符串,请使用:
var MyRegex = new Regex("(?<action>\!?(?:startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
var ms = MyRegex.Match(@"!contains(field,value)");
var action = ms.Groups["action"].Value;
var field = ms.Groups["field"].Value;
var value = ms.Groups["value"].Value;
这是另一个。普遍的想法是将 !?
移到括号之外。
@"(?<!\S)(?<action>!?(?:startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)"
格式化
(?<! \S )
(?<action> #_(1 start)
!?
(?:
startswith
| endswith
| contains
| equals
)
) #_(1 end)
\(
(?<field> \w+ ) #_(2)
,
(?<value> \w+ ) #_(3)
\)
我需要将字符串与预定义关键字列表进行匹配,并将其捕获到一个组中,因为关键字前面可能有一个可选字符。
例子
允许的关键字:
- 包含[=36=]
- 开始于
- 等于
- 结束于
可选字符:!
- input value - comment
contains(field,value) // OK
startswith(field,value) // OK
test(field,value) // NOK (test is not a valid keyword)
equals(field,value) // OK
!startswith(field,value) // OK (optional character ! allowed)
!contains(field,value) // OK (optional character ! allowed)
正则表达式
我尝试使用以下正则表达式:
(?<action>!?startswith|endswith|contains|equals)\((?<field>\w+),(?<value>\w+)\)
我可以成功捕获组(action
、field
、value
),但正则表达式只允许 startswith
的可选字符。我怎样才能分开这两个规则并仍然捕获完整的关键字?像 capture=(optional ?)(any of the allowed keywords)
只需将 !?
放在捕获组之外。
@"!?\b(?<action>startswith|endswith|contains|equals)\((?<field>\w+),(?<value>\w+)\)"
\b
!?
之后的单词边界是非常需要的。
如果要捕获 !startswith 和 !contains,请使用以下命令...
(?<action>!?(startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)
为什么不用
(?<=^|\p{P}|\p{Zs}|\b)(?<action>\!?(?:startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)(?=$|\p{P}|\p{Zs}|\b)
?
你将匹配几乎所有可能的边界+“!?”仅在 ?<action>
组内使用一次,您的操作将保留带有或不带 !
符号的方法名称。
下面是一些测试代码:
var MyRegex = new Regex(
"(?<=^|\p{P}|\p{Zs}|\b)(?<action>\!?(?:startswith|endswit" +
"h|contains|equals))\((?<field>\w+),(?<value>\w+)\)(?=$|\p" +
"{P}|\p{Zs}|\b)",
RegexOptions.IgnoreCase
| RegexOptions.Multiline
| RegexOptions.CultureInvariant
| RegexOptions.Compiled
);
// Capture all Matches in the InputText
var ms = MyRegex.Matches(@"contains(field,value) OK
startswith(field,value) OK
test(field,value) NOK (test is not a valid keyword)
equals(field,value) OK
!startswith(field,value) OK (optional character ! allowed)
!contains(field,value) OK (optional character ! allowed)");
foreach (var capturedgroup in ms.Cast<Match>().ToList())
{
var action = capturedgroup.Groups["action"].Value;
var field = capturedgroup.Groups["field"].Value;
var value = capturedgroup.Groups["value"].Value;
}
或者,如果您必须将方法名称检查为单独的字符串,请使用:
var MyRegex = new Regex("(?<action>\!?(?:startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
var ms = MyRegex.Match(@"!contains(field,value)");
var action = ms.Groups["action"].Value;
var field = ms.Groups["field"].Value;
var value = ms.Groups["value"].Value;
这是另一个。普遍的想法是将 !?
移到括号之外。
@"(?<!\S)(?<action>!?(?:startswith|endswith|contains|equals))\((?<field>\w+),(?<value>\w+)\)"
格式化
(?<! \S )
(?<action> #_(1 start)
!?
(?:
startswith
| endswith
| contains
| equals
)
) #_(1 end)
\(
(?<field> \w+ ) #_(2)
,
(?<value> \w+ ) #_(3)
\)