匹配递归模式而不递归

时间:2016-02-20 15:36:45

标签: c# regex

我目前正在开发一个简单的标记解析器。在我的第一次尝试很容易出错之后,我决定给正则表达式一个镜头并学习语法。到目前为止,我有一个与我的标记匹配的模式。

但就在此刻,我意识到我的情况是我得到了递归。我是正则表达式的新手,因此不知道如何在没有递归的情况下解决这个问题(在C#中可能无法解决)。

作为一个简短的解释,我有以下标记方案:

{TagName} ...内容... {/ TagName} 是内联标记,用于文本格式化(粗体,下划线或更复杂的类型,如邮件链接)。

与所有标记一样,它们可以包含参数。到目前为止这是有效的。

第二种类型是在解析过程中生成动态文本的值标记:

[标签名|参数名称:的parameterValue; ...:...; ...]

我当前的表达式与他们匹配。参数有自己的表达式模式,可以在后期按需解析(工作正常)。

\[([^\|]+)\|(?<Parameters>[^\]]+)\]

我现在遇到的麻烦是我需要嵌套标记。意味着标记的参数值也可以是标记,如下例所示:

[PS|Data:SetToken;default:Token.SetToken([PS|Data:ClassRef], ref [PS|Data:InstanceFieldName])]

现在的问题是我的上面的表达只匹配到第一个嵌套标记的结束括号,从而结束它到早期并打破解析过程。

我认为通过递归我也可以轻松匹配嵌套的那些,截至目前我只需要匹配实际匹配,直到右边的右括号。

我已经看到我的内联标记出现了同样的问题(但通常你不会使用相同的两次,但仍然是一个问题)。

我已经读到有某种正则表达式功能可以匹配与其他人相同的字符数,例如&#34; aaabbb&#34;。这可以解决吗?还有其他解决方案吗?

2 个答案:

答案 0 :(得分:1)

这就是你想要的......

var matches = Regex.Matches("[PS|Data:SetToken;default:Token.SetToken([PS|Data:ClassRef], ref [PS|Data:InstanceFieldName])]",@"\[([^\|]+)\|(?<Parameters>[^\]]+)\]",RegexOptions.Multiline)
                   .Cast<Match>()
                   .Select(match => new 
                   {
                       First = match.Groups[1].Value,
                       Second = match.Groups[2].Value
                   });

Regex Output

答案 1 :(得分:0)

感谢retkomma上的这篇文章,我找到了解决方案。它比思想容易得多。我个人的问题是我有点误解了匹配的群体。毕竟,如果计数不均匀,我就错过了如何使匹配进度无效的知识。因此,这篇文章真的很有帮助。

这是我的价值标记的模式:

(?<!\\)\[
(?'Tag'[^|]*)
(\|
(?'Parameters'
(?>
\[(?'A')|\](?'-A')|.?
)*
)
)?
(?(A)(?!))
(?<!\\)\]

这种模式与正确的部分匹配,保存了正确的群体,并且还允许逃避&#39; [&#39;或者&#39;]&#39;从而使它们无效匹配(如果您需要在不标记任何标记的情况下编写它)。

我仍然试图让内联标记正则表达式模式正常工作。它实际上已经工作了,虽然在一些罕见的情况下(当嵌套的一个具有相同的标签名称时)它仍然无法工作。但最初的问题得到了解答。