我正在用 C# 编写一个小型分词器。
在 PCRE 正则表达式规范中,有简洁的 MARK
关键字:
https://pcre.org/current/doc/html/pcre2syntax.html#SEC23
它是这样工作的:
<?php
$string = 'bar';
$matches = [];
preg_match('~(?|foo(*:1)
|bar(*:2)
|baz(*:3))~x', $string, $matches);
var_dump($matches);
//> array(2) {
//> [0]=> string(3) "bar"
//> ["MARK"]=> string(1) "2"
//> }
如您所见,结果集中的 MARK
参数允许您查看正则表达式的哪个分支实际匹配。不幸的是,.NETs Regex 框架不支持 MARK
关键字。这就是我现在正在做的:
var pattern = @"(
(?<foo>foo)
|(?<bar>bar)
|(?<baz>baz)
)";
var regexOptions = RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace;
var regex = new Regex(pattern, regexOptions);
var matches = regex.Matches("bar");
foreach (Match match in matches)
{
int? mark = null;
if (match.Groups["foo"].Success)
{
mark = 1;
}
else if (match.Groups["bar"].Success)
{
mark = 2;
}
else if (match.Groups["baz"].Success)
{
mark = 3;
}
}
基本上,我需要重构整个正则表达式以查看实际匹配了哪个捕获组。
这似乎倒退了。有没有更好的方法可以做同样的事情?
我需要这个的原因是因为在分词器中我不仅需要知道语法是否有效,还需要知道匹配的分词实际上是哪种分词类型。
最佳答案
如果您坚持使用 MARK
信息或想使用 .NET 中的 PCRE 正则表达式,请查看 PCRE.NET ,它是 PCRE 库的 .NET 包装器(可通过 NuGet 获得)。它提供了许多 PCRE 的功能供 .NET 使用,包括标记检索。
这是一个简短的例子:
using PCRE;
using System.Linq;
namespace PCREdNET
{
class Program
{
static void Main(string[] args)
{
var marks = PcreRegex.Matches("bar", "(?|foo(*:1)|bar(*:2)|baz(*:3))")
.Select(m => m.Mark)
.ToList();
}
}
}
关于c# - 正则表达式 - MARK 以查看匹配的捕获组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49256716/