递归正则表达式:未识别的分组结构

6
我已经写了一个正则表达式来解析BibTex条目,但是我认为我使用了在.NET中不允许的内容,因为我遇到了“未识别的分组结构”异常。
有人能发现我的错误吗?
(?<entry>@(\w+)\{(\w+),(?<kvp>\W*([a-zA-Z]+) = \{(.+)\},)(?&kvp)*(\W*([a-zA-Z]+) = \{(.+)\})\W*\},?\s*)(?&entry)*

可以在 https://regex101.com/r/uM0mV1/1 查看。


哦,不支持使用(?&...)递归命名子模式。 - Wiktor Stribiżew
有没有什么相当的东西可以用? - cholewa1992
只需声明一个变量,然后使用string.Format构建正则表达式。 - Wiktor Stribiżew
1
我看不出来那会如何解决我的问题。 - cholewa1992
你正在尝试通过重复使用模式部分并递归命名子模式来缩短正则表达式模式,对吗?但是在.NET中无法这样做。需要“动态”构建正则表达式。我现在会尝试说明一下。这就是我的意思。不过,我认为你的正则表达式存在一些问题。你想匹配所有单独的条目吗? - Wiktor Stribiżew
我会在.NET中这样做:@(?<type>\w+)\{(?<name>\w+),(?<kvps>\s*(?<attribute>\w+)\s*=\s*\{(?<value>.*?)},?\r?\n)+}。要访问所有键值对,我会使用.Groups["kvps"].Captures属性和/或.Groups["attribute"].Captures.Groups["value"].Captures - Wiktor Stribiżew
2个回答

1
这是我如何捕获您提供字符串中的所有细节:
@(?<type>\w+)\{(?<name>\w+),(?<kvps>\s*(?<attribute>\w+)\s*=\s*\{(?<value>.*?)},?\r?\n)+}

请看:

查看 演示

这个正则表达式很有效,因为C#的正则表达式引擎会将所有捕获的文本保存在堆栈中,并且可以通过Groups["name"].Captures属性访问它们。
以下是展示如何使用它的C#代码:
var pattern = @"@(?<type>\w+)\{(?<name>\w+),(?<kvps>\s*(?<attribute>\w+)\s*=\s*\{(?<value>.*?)},?\r?\n)+}";
var matches = Regex.Matches(line, pattern);
var cnt = 1;
foreach (Match m in matches)
{
    Console.WriteLine(string.Format("\nMatch {0}", cnt));
    Console.WriteLine(m.Groups["type"].Value);
    Console.WriteLine(m.Groups["name"].Value);
    for (int i = 0; i < m.Groups["attribute"].Captures.Count; i++)
    {
        Console.WriteLine(string.Format("{0} - {1}",
              m.Groups["attribute"].Captures[i].Value,
              m.Groups["value"].Captures[i].Value));
     }
     cnt++;
}

输出:

Match 1
article
Gettys90
author - Jim Gettys and Phil Karlton and Scott McGregor
abstract - A technical overview of the X11 functionality. This is an update of the X10 TOG paper by Scheifler \& Gettys.
journal - Software Practice and Experience
volume - 20
number - S2
title - The {X} Window System, Version 11
year - 1990

Match 2
article
Gettys90
author - Jim Gettys and Phil Karlton and Scott McGregor
abstract - A technical overview of the X11 functionality. This is an update of the X10 TOG paper by Scheifler \& Gettys.
journal - Software Practice and Experience
volume - 20
number - S2
title - The {X} Window System, Version 11
year - 1990

Match 3
article
Gettys90
author - Jim Gettys and Phil Karlton and Scott McGregor
abstract - A technical overview of the X11 functionality. This is an update of the X10 TOG paper by Scheifler \& Gettys.
journal - Software Practice and Experience
volume - 20
number - S2
title - The {X} Window System, Version 11
year - 1990

-1

我猜你的命名反向引用是错误的。请参考MSDN。 请尝试以下操作

(?<entry>@(\w+)\{(\w+),(?<kvp>\W*([a-zA-Z]+) = \{(.+)\},)\k<kvp>*(\W*([a-zA-Z]+) = \{(.+)\})\W*\},?\s*)\k<entry>*

\k 关键字仅在递归与第一个完全相同时匹配(就我所理解的而言)(https://regex101.com/r/aZ7xE3/1) - cholewa1992
你说得对。如果重复不需要完全相同,那就更容易了。你不需要回溯引用。使用量词 + 代替:(?<entry>@(\w+)\{(\w+),(?<kvp>\W*([a-zA-Z]+) = \{(.+)\},)+(\W*([a-zA-Z]+) = \{(.+)\})\W*\},?\s*)+ - VV5198722
那也不行,因为它只会生成一个匹配,这样很难提取数据(在我看来)。而大部分的数据将位于未匹配的组中。https://regex101.com/r/pU6jM6/1 - cholewa1992

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接