Я пытался соответствовать .*
С С# регулярное выражение, и получается, что любая строка, в два раза: сначала полную строку, чем во второй раз пустая строка. Я ожидал .*
Чтобы соответствовать всем в одном матче. Я совершенно озадачен, почему это должно быть и как предотвратить это.
Длинная история: мне нужно заменить части имен файлов, с возможностью безоговорочной замены определенной строкой замены. Использование пустой строки в качестве шаблона будет соответствовать и поместить замену после каждого символа строки, как описано в Regex.Replace
. Поэтому я заменяю пустую строку на .*
Перед заменой. Но это, оказывается, выполняет замену двойника.
Чтобы продемонстрировать, что происходит, я использовал:
string input= "sometext";
string pattern= ".*";
MatchCollection matches = Regex.Matches(input, pattern);
foreach (Match match in matches) {
Console.WriteLine("[{0}]", match.Groups[0].Value); }
который дает:
[sometext]
[]
Поскольку анонс String.replaceAll() с жадными кванторами в regex подробно объясняет, *
ведет себя очень жадно в С#/.NET и также соответствует пустой строке в конце строки.
Мое решение - привязать шаблон: ^.*$
. Это делает работу и кажется наиболее понятной, то есть "Сопоставьте все от начала до конца один раз".
Другая возможность - использовать .+
, Который потребляет всю строку ввода и не может совпадать во второй раз. Однако он имеет недостаток, который не соответствует пустой строке.
Почему это соответствует второй раз пустой строкой, когда она уже соответствует целой строке?
Потому что регулярное выражение равно .*
которое будет соответствовать нулю или больше. Таким образом, нулевое вхождение дает пустую строку, начиная с конца ввода строки
Решение
С помощью
.+
соответствует одному или нескольким символам
string text = "sometext";
string expression = ".+";
MatchCollection matches = Regex.Matches(text, expression);
foreach (Match match in matches) {
Console.WriteLine("[{0}]", match.Groups[0].Value); }
Дает вывод как
[sometext]