Полностью пересмотренный ответ (первые два комментария были за предыдущий, неполный ответ):
Я понял, как этого добиться, чтобы я мог «заменить все» на результатах.
string input = @"a<a<<a>>a<a>a>a<a>a";
Regex reg = new Regex(@"
(?<=
<
[^<>]*
(?(ReverseDepth)(?!))
(?:
(?:
<(?<-ReverseDepth>)
|
>(?<ReverseDepth>)
)
[^<>]*
)*
)
a
", RegexOptions.IgnorePatternWhitespace);
Console.WriteLine(reg.Replace(input, "b"));
Это дает следующий вывод:
a<b<<b>>b<b>b>a<b>a
Теперь я понимаю, что в моем вопросе это не указано, но я никогда не задумывался о том, чтобы проверить, закрывается ли группа полностью или нет, поскольку текст, к которому я собираюсь применить это, предварительно проверен на xml. Однако, чтобы сопоставить мой ответ на вопрос и предотвратить сопоставление «а» в "<a"
, вместо приведенного мною здесь можно использовать следующее регулярное выражение:
Regex reg = new Regex(@"
(?<=
<
[^<>]*
(?(ReverseDepth)(?!))
(?:
(?:
<(?<-ReverseDepth>)
|
>(?<ReverseDepth>)
)
[^<>]*
)*
)
a
(?=
(?:
(?:
<(?<Depth>)
|
>(?<-Depth>)
)
[^<>]*
)*
(?(Depth)(?!))
[^<>]*
>
)
", RegexOptions.IgnorePatternWhitespace);