Регулярные выражения
Регулярные выражения — это специализированный язык шаблонов для обработки текста. Он позволяет описывать правила поиска, проверки, извлечения и замены фрагментов строк. С его помощью можно искать и извлекать фрагменты текста, проверять формат строк и выполнять сложные замены.
В PascalABC.NET регулярные выражения задаются обычными строками, например '\d+', '\w+', '\bкот\b'.
Основные операции доступны как методы строк: IsMatch, MatchValue, MatchValues, Matches, RegexReplace.
Проверка соответствия
Метод IsMatch проверяет, содержит ли строка фрагмент, соответствующий регулярному выражению.
begin
var s := 'abc123';
Println(s.IsMatch('\d+'));
Println(s.IsMatch('[A-Z]+'));
end.
Результат:
True
False
Первое совпадение
Метод MatchValue возвращает первое найденное совпадение в виде строки.
begin
var s := 'Цена 120 рублей, скидка 15 процентов';
Println(s.MatchValue('\d+'));
end.
Результат:
120
Все совпадения
Метод MatchValues возвращает все найденные совпадения как последовательность строк.
begin
var s := 'Цена 120 рублей, скидка 15 процентов';
s.MatchValues('\d+').Println;
end.
Результат:
120 15
Позиции найденных фрагментов
Метод Matches возвращает последовательность объектов Match, содержащих найденный текст, его позицию и длину.
begin
var s := 'red green blue';
foreach var m in s.Matches('\w+') do
Println(m.Value, m.Index, m.Length);
end.
Результат:
red 0 3
green 4 5
blue 10 4
Классы символов
В регулярных выражениях можно задавать классы символов: \d — цифра, \w — буква, цифра или _, \s — пробельный символ.
begin
var s := 'abc 123 45.6';
s.MatchValues('\d+').Println;
s.MatchValues('\w+').Println;
end.
Результат:
123 45 6
abc 123 45 6
Классы символов можно задавать и явно:
begin
var s := 'cat cot cut cit';
s.MatchValues('c[ao]t').Println;
end.
Результат:
cat cot
Квантификаторы
Квантификаторы задают количество повторений предыдущего элемента шаблона.
* 0 или более
+ 1 или более
? 0 или 1
{n} ровно n
{n,} не менее n
{n,m} от n до m
Например, найдём числа, содержащие от двух до четырёх цифр.
begin
var s := '7 12 345 6789 12345';
s.MatchValues('\b\d{2,4}\b').Println;
end.
Результат:
12 345 6789
Альтернатива и набор символов
Символ | задаёт выбор между вариантами, а квадратные скобки — выбор одного символа из набора.
begin
var s := 'кот кит кат крот';
s.MatchValues('кот|кит').Println;
s.MatchValues('к[ио]т').Println;
end.
Результат:
кот кит
кот кит
Граница слова
Последовательность \b обозначает границу слова. С помощью Matches можно увидеть не только найденные фрагменты, но и их позиции в строке.
begin
var s := 'бойкот котомка кот';
foreach var m in s.Matches('\bкот') do
Println(m.Value, m.Index);
Println;
foreach var m in s.Matches('кот\b') do
Println(m.Value, m.Index);
Println;
foreach var m in s.Matches('\bкот\b') do
Println(m.Value, m.Index);
end.
Результат:
кот 7
кот 15
кот 3
кот 15
кот 15
Игнорирование регистра
Опция RegexOptions.IgnoreCase позволяет выполнять поиск без учёта регистра символов.
begin
var s := 'PaScal PASCAL pascal Python';
s.MatchValues('pascal', RegexOptions.IgnoreCase).Println;
end.
Результат:
PaScal PASCAL pascal
Простая замена
Метод RegexReplace заменяет все фрагменты, соответствующие регулярному выражению.
begin
var s := 'один два три';
Println(s.RegexReplace(' +', ' '));
end.
Результат:
один два три
Замена найденного фрагмента
В строке замены $0 обозначает всё найденное совпадение.
begin
var s := 'один два три';
Println(s.RegexReplace('\w+', '<$0>'));
end.
Результат:
<один> <два> <три>
Замена с группами
Круглые скобки создают группы, а $1, $2, $3 позволяют использовать найденные группы в строке замены.
begin
var s := '2026/08/16';
s := s.RegexReplace(
'(\d{4})/(\d{2})/(\d{2})',
'$3.$2.$1'
);
Println(s);
end.
Результат:
16.08.2026
Замена с лямбдой
Вместо строки замены можно передать лямбда-выражение, вычисляющее новое значение для каждого совпадения.
begin
var s := 'один два четыре';
Println(
s.RegexReplace(
'\w+',
m -> $'{m.Value}({m.Length})'
)
);
end.
Результат:
один(4) два(3) четыре(6)
Вычисляемая замена
Лямбда позволяет использовать найденные группы и выполнять вычисления при замене.
begin
var s := '10+2 5+31 777+333';
var result := s.RegexReplace(
'(\d+)\+(\d+)',
m -> (
m.Groups[1].Value.ToInteger +
m.Groups[2].Value.ToInteger
).ToString
);
Println(result);
end.
Результат:
12 36 1110
Жадный и ленивый поиск
По умолчанию квантификаторы стараются захватить как можно больше символов; добавление ? делает их ленивыми.
begin
var s := '"one" and "two"';
s.MatchValues('".*"').PrintLines;
s.MatchValues('".*?"').PrintLines;
end.
Результат:
"one" and "two"
"one"
"two"
Положительный просмотр вперёд
Конструкция (?=...) проверяет, что после найденного фрагмента следует заданный шаблон, но не включает его в результат.
В данном примере ищутся все слова, после которых идет запятая.
begin
var s := 'Привет, как дела, что нового?';
s.MatchValues('\b\w+\b(?=,)').Println;
end.
Результат:
Привет дела
Отрицательный просмотр назад
Конструкция (?<=...) проверяет, что перед найденным фрагментом находится заданный шаблон, но не включает его в результат.
В данном примере ищутся все цены в долларах.
begin
var s := 'Цены: $100, $200, 300 рублей';
s.MatchValues('(?<=\$)\d+').Println;
end.
Результат:
100 200