【问题标题】:Regex - MARK to see which capture group was matched正则表达式 - MARK 以查看匹配的捕获组
【发布时间】:2018-03-13 12:51:50
【问题描述】:

我正在用 C# 编写一个小型标记器。

在 PCRE 正则表达式规范中有简洁的 MARK 关键字:
https://pcre.org/current/doc/html/pcre2syntax.html#SEC23

这就是它的工作原理:

https://3v4l.org/ErCrp

<?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 参数允许您查看正则表达式的哪个分支实际匹配。不幸的是,.NET 正则表达式框架不支持 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;
    }
}

基本上,我需要重构整个正则表达式以查看实际匹配的捕获组。

这似乎倒退了。有没有更好的方法可以做同样的事情?

我需要这个的原因是因为在标记器中我不仅需要知道语法是否有效,还需要知道匹配的标记实际上是哪种标记类型。

【问题讨论】:

  • 命名捕获组怎么样?
  • 将可能的标记放入字典并循环遍历它们。然后尝试在字符串的开头进行匹配,看看哪个匹配 - 在这里,获取令牌名称,使用字符串并打破循环。
  • 如果您需要确定匹配的是哪个令牌,为什么不直接读取外部组的值?
  • @revo 我当前的解决方案确实使用命名捕获组;)
  • 你能告诉我这个我可以将正确的令牌类型(它是一个枚举)传递给 MARK 值吗?我没听懂。

标签: c# .net regex pcre


【解决方案1】:

如果您坚持使用 MARK 信息或希望使用 .NET 中的 PCRE 正则表达式,请查看PCRE.NET,它是 PCRE 库的 .NET 包装器(可通过 NuGet 获得)。它提供了许多用于 .NET 的 PCRE 功能,包括标记检索。

这是一个简短的例子:

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# 的 PCRE 兼容性的一些上下文:stackoverflow.com/a/26504537/8291949
  • 好吧,我不是坚持使用`MARK`,我只是想知道是否有类似的解决方案不需要重建正则表达式本身的分支。图书馆看起来很有趣!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多