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 に答える