我有一个正则表达式.它包含必需的命名捕获组和一些可选的命名捕获组.它捕获单个匹配并将这些部分解析为我需要的命名组.
除此之外,现在我需要重复一遍.
本质上,我的正则表达式表示(可能)更长的字符串中的单个原子单元.而不是完全匹配我的正则表达式,目标字符串通常包含正则表达式的重复实例,由点''分隔.字符.
例如,如果这是我的正则表达式捕获的内容: <some match>
实际的字符串可能看起来像这些:
<some match><some match>.<some other match><some match>.<some other match>.<yet another match>修改原始正则表达式,考虑重复模式,忽略点的最简单方法是什么?
我不确定它是否真的需要,但这里是我正用于捕获单个段的正则表达式.同样,我想增强此功能以考虑可选的其他细分.我想让每个段在结果集中显示为另一个"匹配";
^(?<member>[A-Za-z_][A-Za-z0-9_]*)(?:\[(?<index>[0-9]+)\])?(?:\[(?<index2>[0-9]+)\])?(?:\[(?<index3>[0-9]+)\])?$
Run Code Online (Sandbox Code Playgroud)
它旨在解析类路径,最多包含三个可选的索引访问器.(即" member.sub_member[0].sub_sub_member[0][1][2]")
我怀疑答案涉及前瞻或后视,对此我并不完全熟悉.
我目前使用String.Split来分隔字符串段.但我认为如果正则表达式的增强足够简单,我跳过额外的Split步骤,并重新使用正则表达式作为验证机制.
编辑:
作为齿轮中的另一个扳手,我想不允许任何点'.' 从字符串的开头或结尾开始的字符.它们应仅作为路径段之间的分隔符存在.
您实际上不需要使用任何环视。(^|\.)您可以在主模式前面放置一个,然后+在其后面放置一个。这将允许您制作重复的、.分隔的序列。为了简单起见,我还建议您将组合<index>并为单个捕获(我曾经*匹配任意数量的索引,但您也可以轻松地{0,3}仅匹配最多 3 个索引)。最终的模式是:
(?:(?:^|\.)(?<member>[A-Za-z_][A-Za-z0-9_]*)(?:\[(?<index>[0-9]+)\])*)+$
Run Code Online (Sandbox Code Playgroud)
例如:
var input = "member.sub_member[0].sub_sub_member[0][1][2]";
var pattern = @"(?:(?:^|\.)(?<member>[A-Za-z_][A-Za-z0-9_]*)(?:\[(?<index>[0-9]+)\])*)+$";
var match = Regex.Match(input, pattern);
var parts =
(from Group g in match.Groups
from Capture c in g.Captures
orderby c.Index
select c.Value)
.Skip(1);
foreach(var part in parts)
{
Console.WriteLine(part);
}
Run Code Online (Sandbox Code Playgroud)
这将输出:
member
sub_member
0
sub_sub_member
0
1
2
Run Code Online (Sandbox Code Playgroud)
更新:此模式将确保字符串不能有任何前导或尾随点。这是一个怪物,但它应该可以工作:
^(?<member>[A-Za-z_][A-Za-z0-9_]*)(?:\[(?<index>[0-9]+)\]){0,3}(?:\.(?<member>[A-Za-z_][A-Za-z0-9_]*)(?:\[(?<index>[0-9]+)\]){0,3})*$
Run Code Online (Sandbox Code Playgroud)
或者这个,尽管我不得不放弃我的“不环顾四周”的想法:
^(?!\.)(?:(?:^|\.)(?<member>[A-Za-z_][A-Za-z0-9_]*)(?:\[(?<index>[0-9]+)\]){0,3})*$
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2501 次 |
| 最近记录: |