Regex.Replace не работает с обратной ссылкой - PullRequest
1 голос
/ 18 сентября 2009

Я сделал приложение, предназначенное для подготовки файлов к переводу с использованием списков регулярных выражений.

Он запускает каждое регулярное выражение в файле, используя Regex.Replace. Существует также модуль инспектора, который позволяет пользователю видеть совпадения для каждого регулярного выражения в списке.

Это работает хорошо, за исключением случаев, когда регулярное выражение содержит обратную ссылку, Regex.Replace ничего не заменяет, но инспектор показывает соответствия правильно (поэтому я знаю, что регулярное выражение действительно и соответствует тому, что должно).

sSrcRtf = Regex.Replace(sSrcRtf, sTag, sTaggedTag,
  RegexOptions.Compiled | RegexOptions.Singleline);

sSrcRtf содержит код RTF страницы. sTag содержит регулярное выражение в скобках. sTaggedTag содержит $ 1, окруженный кодом форматирования тега.

Чтобы привести пример:

sSrcRtf = Regex.Replace("the little dog", "((e).*?\1)", "$1", 
  RegexOptions.Compiled | RegexOptions.Singleline);

не работает. Но

sSrcRtf = Regex.Replace("the little dog", "((e).*?e)", "$1", 
  RegexOptions.Compiled | RegexOptions.Singleline);

делает. (конечно, есть некоторый код RTF около $ 1)

Есть идеи, почему это так?

Ответы [ 3 ]

2 голосов
/ 18 сентября 2009

Технически у вас есть две группы совпадений, внешние и внутренние скобки. Почему бы вам не попробовать обратиться к внутреннему набору в качестве второго захвата, например ::10000

((e).*?\2)

Ваш синтаксический анализатор, вероятно, считает, что внешний захват равен \ 1, и нет смысла ссылаться на него изнутри.

Также обратите внимание, что ваша замена ничего не даст, так как вы просите заменить ту часть, которая соответствует самой себе. Я не уверен, каково ваше предполагаемое поведение, но если вы пытаетесь извлечь только совпадение и отбросить оставшуюся строку, вам нужно что-то вроде:

.*((e).*?\2).*
0 голосов
/ 18 сентября 2009

Как уже упоминалось, есть несколько дополнительных групп, которые были захвачены. Ваша замена не ссылается на правильную.

Ваше текущее регулярное выражение должно быть переписано как (опущенные параметры):

Regex.Replace("the little dog", @"((e).*?\2)", "$2")
// or
Regex.Replace("the little dog", @"(e).*?\1", "$1")

Вот еще один пример, который соответствует двойным словам и указывает, какие обратные ссылки работают:

Regex.Replace("the the little dog", @"\b(\w+)\s+\1\b", "$1")  // good
Regex.Replace("the the little dog", @"\b((\w+)\s+\2)\b", "$1") // no good
Regex.Replace("the the little dog", @"\b((\w+)\s+\2)\b", "$2") // good
0 голосов
/ 18 сентября 2009

Вы используете ссылку на группу внутри группы, на которую ссылаетесь.

"((e).*?\1)" // first capturing group
"(e)" // second capturing group

Я не уверен на 100%, но я не думаю, что вы можете ссылаться на группу внутри этой группы. Для начала, что вы ожидаете, что обратная ссылка будет совпадать, так как она еще не завершена?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...