Ограничение жадности в регулярках C#
Регулярные выражения по умолчанию жадные. Это значит, что они захватывают максимальное возможное количество символов. Разберем на примере. Пусть у нас есть вот такая строка:
string txt = "aeeex zzz x kkk";
Console.WriteLine(txt);
В этой строке хотим найти подстроку
"'aeeex'" по следующему шаблону:
буква "'a'", затем любой символ
один или более раз, затем буква "'x'":
using System.Text.RegularExpressions;
string txt = "aeeex zzz x kkk";
string res = Regex.Replace(txt, @"a.+x", "!");
Console.WriteLine(res);
Хотя нам нужно получить строку "'! zzz
x kkk'", выведется строка "'! kkk'".
Все дело в том, что наша регулярка ищет
все символы от буквы "'a'" до буквы
"'x'". Но в нашей строке две буквы
"'x'"! Из-за жадности получается, что
регулярка ищет до самого последнего икса,
тем самым захватывая не то, что нам было
нужно.
Конечно, зачастую такое поведение нам и требуется. Но конкретно в этом случае нужно отменить жадность и сказать регулярке, чтобы она искала до первого икса. В этом случае следует после оператора повторения поставить знак вопроса:
using System.Text.RegularExpressions;
string txt = "aeeex zzz x kkk";
string res = Regex.Replace(txt, @"a.+?x", "!");
Console.WriteLine(res);
Жадность можно ограничить у всех операторов
повторения: и *, и ?, и
{} - вот так: *?, ??
и {}?.
Дана строка:
string txt = "aba accca azzza wwwwa";
Напишите регулярку, которая найдет все
строки, по краям которых стоят буквы
"'a'", и заменит каждую из них на
"'!'". Между буквами "'a'" может
быть любой символ (кроме "'a'").