Regex.Replace без конца и конца строки имеет некоторые очень странные эффекты .... Что здесь происходит? - PullRequest
10 голосов
/ 10 февраля 2012

При ответе на этот вопрос C # Regex Replace и * был поднят вопрос о том, почему существует проблема. При игре я выдает следующий код:

    string s = Regex.Replace(".A.", "\w*", "B");
    Console.Write(s);

Это имеет выход: B.BB.B

Я получаю, что строка длины 0 совпадает до и после символа ., но почему А заменяется на 2 B.

Я мог бы понять B.BBB.B как замену строк нулевой длины по обе стороны от A или B.B.B Но фактический результат смущает меня - любая помощь приветствуется.

Или, как выразился AakashM:

Почему Regex.Matches("A", "\w*").Count равно 2, а не 1 или 3?

Ответы [ 4 ]

12 голосов
/ 10 февраля 2012

После \ w

есть звезда

Это означает « ноль или много», что означает:

  • Первый символ - точка, это НЕ \ w, поэтому здесь есть ноль \ w , замените на B
  • Далее у нас есть сама точка, которую нельзя заменить
  • A заменяется на B
  • ноль \ w перед следующей точкой, заменить на B
  • точка, не заменяемая
  • Конец строки, ноль \ w, поэтому замените на B снова.

Выражение \w{0,} будет иметь тот же эффект.

Если вы хотите избежать этого, используйте «плюс», что означает «хотя бы один»: \w+

6 голосов
/ 10 февраля 2012

То же поведение, что и

Regex.Replace("", "\w*", "B") приводит к B
Regex.Replace("A", "\w*", "B") приводит к BB

См. здесь на Regexr

Для строки ".A."\w* соответствует перед первой точкой - пустой строке, затем по «A», после «A» - пустой строке и после последней точки - пустой строке.

Объяснение

Вы можете вспомнить схему, в которой есть символы, \w* съел "A", следующий символ - точка, поэтому это совпадение завершено и заменено.Но начальная позиция для продолжения сопоставления с образцом все еще находится между точкой A и точкой.Точка не может быть сопоставлена, поэтому она соответствует пустой строке перед точкой, но затем эта позиция выполняется, и следующая начальная позиция находится после точки.

4 голосов
/ 10 февраля 2012

, потому что \ w * - жадное регулярное выражение, и оно пытается найти наибольшую последовательность.Таким образом, он соответствует "nothing" перед точкой, затем "nothing"A между двумя точками, затем "nothing" перед второй точкой и, наконец, "nothing" после второй точки.

2 голосов
/ 10 февраля 2012

По умолчанию это жадное совпадение, поэтому оно ищет максимум совпадений.Вот почему вы получаете этот результат.

Если вы делаете это неохотно, как этот

string s = Regex.Replace(".A.", "\\w*?", "B");

Вы получите этот результат, потому что он находит минимальные совпадения.

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