1

目前我正在使用某种在每个级别上都有一个正则表达式的树来将一些任意文本文件解析成一棵树。到目前为止,一切正常,正则表达式结果被传递给子节点以进一步解析文本。为了获得节点和子节点之间的链接,节点本身也有一个名称,在正则表达式中用作组名。因此,在解析了一些文本之后,我将得到一个包含一些命名组的正则表达式,并且节点本身也包含具有相同名称的子节点,这会导致递归结构进行一些任意解析。

现在我遇到了麻烦,为了让下一步中这棵树的处理更容易一些,我需要在我的树中不同节点下的文本文件中的相同信息。由于事实上,这可能有点难以理解,这是一个单元测试,显示了我想要实现的目标:

string input = "Some identifier=Just a value like 123";
// ToDo: Change the pattern, that the new group 'anotherName' will contain the same text as 'key'.
string pattern = "^(?'key'.*?)=(?'value'.*)$";
Regex regex = new Regex(pattern);
Match match = regex.Match(input);

var key = match.Groups["key"];
var value = match.Groups["value"];
var sameAsKeyButWithOtherGroupName = match.Groups["anotherName"];

Assert.That(key, Is.EqualTo(sameAsKeyButWithOtherGroupName));

任何想法如何让这个工作?

4

2 回答 2

1

要在 .NET 模式中调用反向引用,您必须指定\k<name_of_group>语法。可以试试这个:

bool foundMatch = false;
try {
    foundMatch = Regex.IsMatch(subjectString, @"^(?<authorName>(?'key'.*?)=\k<key>)$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

解释:

<!--
^(?<authorName>(?'key'.*?)=\k'key')$

Assert position at the beginning of the string «^»
Match the regular expression below and capture its match into backreference with name “authorName” «(?<authorName>(?'key'.*?)=\k'key')»
   Match the regular expression below and capture its match into backreference with name “key” «(?'key'.*?)»
      Match any single character that is not a line break character «.*?»
         Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
   Match the character “=” literally «=»
   Match the same text as most recently matched by the named group “key” «\k'key'»
Assert position at the end of the string (or before the line break at the end of the string, if any) «$»
-->
于 2012-05-14T09:48:39.223 回答
1

在阅读了 Cylians 的回答并向他写了我自己的评论后,我对反向引用做了更多的研究,我的测试将通过这个稍微改变的正则表达式成功:

string input = "Some identifier=Just a value like 123";
string pattern = @"^(?'key'.*?)(?'anotherName'\k<key>)=(?'value'.*)$";
Regex regex = new Regex(pattern);
Match match = regex.Match(input);

var key = match.Groups["key"];
var value = match.Groups["value"];
var sameAsKeyButWithOtherGroupName = match.Groups["anotherName"];

Assert.That(key, Is.EqualTo(sameAsKeyButWithOtherGroupName));

所以结论很简单:如果你需要在另一个名称下的同一个组,只需声明这个组并将另一个组的内容用作模式字符串。

于 2012-05-14T10:20:23.777 回答