Regex.Replace без начала и окончания строки имеет некоторые очень странные эффекты... Что здесь происходит?

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

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

У этого есть вывод: B.BB.B

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

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

Или, как сказал AakashM:

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

Ответ 1

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

Ответ 2

Существует звезда после \w

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

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

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

Если вы хотите избежать этого, используйте "plus", что означает "по крайней мере один": \w+

Ответ 3

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

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

Смотрите здесь, в Regexr

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

Объяснение

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

Ответ 4

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

Если вы делаете это с неохотой, например,

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

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

B.BAB.B