我正在尝试使用.net内核学习正则表达式。特别是,我正试图使用它们来解析程序集中嵌入资源的列表,如下所示。
正则表达式模式
^([w._])*((?<create>.Postgres.Create.)|(?<drop>.Postgres.Drop.)([w._]))*$
从嵌入资源列表生成的示例文本
Mynamespace.Postgresql.Create.select_course_units.sql
Mynamespace.Postgresql.Drop.drop_select_course_units.sql
Mynamespace.Postgresql.Create.select_units.sql
Mynamespace.Postgresql.Drop.drop_select_units.sql
...
正则表达式有两个名为Postgres的捕获组。分别创建和Postgres。删除捕获。我的正则表达式找到了这两个匹配项,但捕获中没有存储任何用于创建或删除组的内容。是否可以让它存储捕获,以便确定匹配是否包含创建或删除?
public void ReadCreateStoredProcedures()
{
const string pattern = @"^([w._])*((?<create>.Postgres.Create.)|(?<drop>.Postgres.Drop.)([w._]))*$";
Regex rx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multiline);
string[] resNames = typeof(CourseContext).Assembly.GetManifestResourceNames();
string text = string.Join("n",resNames);
MatchCollection matches = rx.Matches(text);
foreach(Match match in matches)
{
Console.WriteLine($"Matched{match.Value}");
GroupCollection col = match.Groups;
int lC = col["create"].Length;
int lD = col["drop"].Length;
Console.WriteLine($"Total Create Captures : {lC}");
Console.WriteLine($"Total Drop Captures : {lD}");
foreach(var capture in col["create"].Captures)
{
Console.WriteLine($"Create Capture :: {@capture}");
}
foreach (var capture in col["drop"].Captures)
{
Console.WriteLine($"Drop Capture :: {@capture}");
}
}
}
在您的模式中,您不会获得命名捕获组中的值,因为([w._])*
开头的这一部分将首先匹配,直到字符串结束。
您确实得到了一个带有单个字符的捕获组(而不是命名的捕获组(,该字符将是字符串的最后一个字符,因为当重复捕获组时,该组将包含上一次迭代的值。
以下是可选部件((?<create>.Postgres.Create.))*$
。由于它是可选的,模式可以断言字符串的下一个结尾,并且命名的捕获组不包含值。
注意w
也匹配下划线,并且不必转义字符类中的点
如果您想从Postgresql
开始捕获两个值,您可以使用2个捕获组,例如:
^w+.(?:(?<create>Postgresql.Create(?:.w+)+)|(?<drop>Postgresql.Drop(?:.w+)+))$
解释
^
字符串开始w+.
匹配1个以上单词字符(?:
非捕获组(?<create>
命名组create
Postgresql.Create(?:.w+)+ Match Postgresql.Create and repeat matching a
`和1个以上的单词字符
)
关闭组|
或(?<drop>
命名组drop
Postgresql.Drop(?:.w+)+
与Postgresql.Drop相同
)
命名组drop
)
关闭非捕获组$
字符串结束
.NET正则表达式演示(单击Table
选项卡(