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