2. План лекции
Понятие регулярного выражения
Примеры применения регулярных
выражений
Правила написания (синтаксис)
регулярных выражений
Классы для работы с регулярными
выражениями
Regex
Match
Group
3. Предисловие
При обработке текстовой информации
часто возникают ситуации требующие
удаления, замены или вставки
определенных символов или слов.
Может возникать необходимость обмена
информацией с другими системами
которые помимо других кодировок
текстовой информации используют
устаревшие форматы файлов.
4. Понятие регулярного
выражения
Регулярное выражение (regular expression,
regexp, RegEx) - механизм, позволяющий
задать шаблон для строки и осуществить
поиск данных, соответствующих этому
шаблону в заданном тексте.
Кроме того, дополнительные функции по
работе с регулярными выражениями
позволяют получить найденные данные в виде
массива строк, произвести замену в тексте по
шаблону, разбиение строки по шаблону и т.п.
5. Поиск файла по маске имени
Поиск файлов
по имени с
использованием
маски (шаблона
имени файла) и
команды dir
C:Dev-Cppbin> dir /b *.exe
addr2line.exe
ar.exe
as.exe
c++.exe
c++filt.exe
cpp.exe
dlltool.exe
dllwrap.exe
g++.exe
gcc.exe
gcov.exe
gdb.exe
6. Поиск файла с применением
регулярного выражения
Поиск файлов
по имени с
использованием
регулярного
выражения и
менеджера
файлов Unreal
Commander*
(*доступен на сайте
http://x-diesel.com/)
^[a-z](w|+|-)*d+(w|+|-)*.exe$ exe-файлы с именами не короче 2
символов (без расширения), которые
начинаются с буквы и в имени
содержат хотя бы одну цифру
Повторение в количестве от 0 до ∞ раз:
большие и малые буквы, цифры, _ , +, –
7. Проверка соответствия
формату
Регулярное выражение для проверки того,
что строка содержит корректный e-mail адрес
^w+([.w]+)*w@w((.w)*w+)*.w{2,3}$
На первый взгляд ничего (кроме разве что
символа @) не понятно , но если знать
правила по которым строятся подобные
шаблоны, вы в полной мере сможете
оценить позитивные стороны их
использования
8. Синтаксис регулярных
выражений
Большинство символов в регулярном
выражении представляют сами себя за
исключением специальных символов
[ ] ^ $ . | ? * + ( ) { }
Специальные символы могут обозначать
сами себя (становится обычными) если:
предварены символом
или
заключены между Q и E (т.е. «экранированы»)
9. Метасимволы положения в
строке
Метасимвол Описание
^ Начало строки (начало новой строки в тексте)
$ Конец строки (перед началом новой строки)
A Начало строки
Z Конец строки (или пред n в конце строки)
z Конец строки
G После предыдущего найденного
b Граница слова
B Не граница слова
10. Метасимволы для
эскейп-последовательностей
Метасимвол Описание
a Звонок, звуковой сигнал (аналогичен u0007)
t Табуляция (аналогичен u0009)
r Возврат каретки (аналогичен u000D)
v Вертикальная табуляция (аналогичен u000B)
f Перевод формы (аналогичен u000C)
n Новая строка (аналогичен u000A)
e Escape (аналогичен u001B)
040 ASCII-код в восьмеричной системе равный 40
x20 ASCII-код в шестнадцатеричной системе равный 20
cC ASCII-код управляющего символа для Ctrl+C
u0020 Символ Unicode с шестнадцатеричным кодом 20
Символ как сам по себе (аналогично +, * и т.д.)
11. Метасимволы
количества повторений
Метасимвол Описание
* Ноль или более повторений
+ Одно или более повторений
? Опциональное присутствие - ноль или один
{n} Заданное (целым положительным числом n)
количество повторений – Равно n раз
{m,n} От m до n раз
{m,} Не менее m раз
{,n} Не более n раз
? Употребляемый после метасимволов количества
повторений определяет логику работы – определяет
режим «жадный/ленивый»
12. Жадная и ленивая
квантификация
Пример неоднозначности:
При поиске тегов в тексте HTML ориентируясь
на символы угловых скобок < >, мы можем:
A. Найти (первый или каждый) один тег –
B. Найти весь текст между первым и последним
тегами –
<p><b>Википедия</b> — свободная энциклопедия, в
которой <i>каждый</i> может изменить или дополнить
любую статью</p>.
<p><b>Википедия</b> — свободная энциклопедия, в
которой <i>каждый</i> может изменить или дополнить
любую статью</p>.
13. Жадный, ленивый и ревнивый
Знак вопроса после
метасимвола вынуждает
искать кратчайший вариант
Знак + перед квалификатором
определяет «ревнивую»
квалификацию - «жадную»,
способную возвращаться к
просмотренному фрагменту
для пересмотра
Жадный Ленивый
* *?
+ +?
{n,} {n,}?
Жадный Ревнивый
* *+
? ?+
+ ++
{n,} {n,}+
Пример Результат
ab(xa)*+a Находит abxaabxaa; но не abxaabxaa,
так как буква a уже занята
14. Метасимволы диапазонов и
универсальные символы
Метасимвол Описание
. Любой символ кроме n
x|y Любой из двух символов x или y
[xyz] Один из заданных символов, т.е. x, y или z
[a-z] Диапазон символов от a до z
При определении диапазонов можно
указывать несколько интервалов в одной
паре квадратных скобок, например:
[a-zA-Z] или [1-9A-F]
15. Метасимволы обозначения
групп символов
Метасимвол Описание
d Символы десятичных цифр. Аналог [0-9].
D Символы отличные от символов десятичных цифр.
Аналог [^0-9].
s Пробельные символы (пробел, табуляция и т.д.).
Аналог [fnrtv].
S Символы не относящиеся к пробельным.
Аналог [^fnrtv].
w Символы употребляемые в «словах»
(идентификаторах). Аналог [A-Za-z0-9_].
W Символы не употребляемые в словах.
Аналог [^A-Za-z0-9_].
16. Другие символы
Для обозначения «любой символ
включая n» можно использовать
[sS]
Круглые скобки можно использовать для
объединения или выделения групп,
например:
(a|A)+
Добавление символов [ и ] в наборы:
[][%$]
17. Примеры регулярных
выражений (1)
Выражение для проверки того что строка
представляет четырехзначное число в
десятичной системе счисления
^d{4}$
Начало
Цифра , повторенная 4 раза
Конец
18. Примеры регулярных
выражений (2)
Выражение для поиска в тексте слов
начинающихся на букву А
bA[a-z]*b
Начало слова
Первая буква - большая
Еще сколько угодно
маленьких букв
19. Примеры регулярных
выражений (3)
Варианты записи телефонных номеров:
+380501234567
+38(050)1234567
0501234567
(050)1234567
1234567
Один из возможных вариантов
регулярного выражения для поиска:
((+d{2})?((d{3})|d{3}))?d{7}
20. Реализация RegEx’ов в
программировании
Многие языки программирования имеют
встроенный средства для работы с
регулярными выражениями, например
PHP, Perl, Python, Tcl, Ruby и другие
активно используют этом механизм
Полное описание синтаксиса регулярных
выражений можно найти в сети Интернет
http://www.php.net/manual/en/pcre.pattern.syntax.php
Также в Интернет есть поясняющие
описания (например wikipedia)
21. Регулярные выражения в C#
Для работы с регулярными выражениями
используются классы из пространства
имен System.Text.RegularExpressions :
Regex
Match
MatchCollection
Capture
Group
и другие
22. Простейший пример
Программа для синтаксической
корректности e-mail адреса:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
string inp = Console.ReadLine();
if (Regex.IsMatch(inp,
@"^w+([.w]+)*w@w((.w)*w+)*.w{2,3}$"))
Console.WriteLine("Это e-mail!");
else
Console.WriteLine("Ошибка");
}
}
23. Получение данных от
поиска по Regex
// Запрос четырехзначного числа
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{ string inp;
string pattern = @"^d{4}$";
int number = 0;
Match m;
do{ // цикл: пока нет совпадений
inp = Console.ReadLine(); // получение строки
m = Regex.Match(inp, pattern); // поиск
if (m.Success) // если есть совпадение
number = int.Parse(m.Value);
} while(m == Match.Empty);
Console.WriteLine(number);
}
}
24. Объект класса Regex
// Запрос четырехзначного числа
using System;
using System.Text.RegularExpressions;
class Program
{ static void Main(string[] args)
{
int number = 0;
string inp;
Match m;
Regex reg = new Regex(@"^d{4}$");
do{ // цикл: пока нет совпадений
inp = Console.ReadLine(); // получение строки
m = reg.Match(inp); // поиск
if (m.Success) // если есть совпадение
number = int.Parse(m.Value);
} while(m == Match.Empty);
Console.WriteLine(number);
}
}
25. Получение всех совпадений:
перебор
// Перебор найденных совпадений
using System;
using System.Text.RegularExpressions;
class Program
{ static void Main(string[] args)
{
Regex rx = new Regex(@"bA[a-z]*b");
Match m = rx.Match(Console.ReadLine());
while (m.Success) // пока есть совпадения
{ // перебираем их и выводим на экран
Console.WriteLine(m.Value);
m = m.NextMatch(); // следующей...
}
}
}
26. Получение всех совпадений:
полный список совпадений
// Использование коллекции
using System;
using System.Text.RegularExpressions;
class Program
{ static void Main(string[] args)
{
Regex rx = new Regex(@"bA[a-z]*b");
MatchCollection all =
rx.Matches(Console.ReadLine());
Console.WriteLine("Найдено {0}",
all.Count);
foreach (Match m in all)
Console.WriteLine(m.Value);
}
}
27. Выборка телефонных
номеров из текста
// Поиск в строке номеров телефонов
using System;
using System.Text.RegularExpressions;
class Program
{ static void Main(string[] args)
{
Regex phone =
new Regex(@"((+d{2})?((d{3})|d{3}))?d{7}");
MatchCollection result =
phone.Matches(Console.ReadLine());
string[] numbers = new string[result.Count];
for (int i = 0; i < result.Count; i++)
numbers[i] = result[i].Value;
foreach (string s in numbers)
Console.WriteLine(s);
}
}
28. Пример работы программы
Входные данные:
Результат:
Номер комнаты 120 телефон 7884028 (внутренний
4028), мобильный (050)9544552
7884028
(050)9544552
29. Изменение формата записи
номеров телефонов
Необходимый
формат вывода:
###-##-##
Например:
(050)1234567
станет
123-45-67
Допустимые
форматы ввода:
+############
+##(###)#######
##########
(###)#######
#######
30. // Переформатирование номеров телефонов
using System;
using System.Text.RegularExpressions;
class Program
{ static string ReformatPhone(string s)
{
Match m = Regex.Match(s,
@"^(+d{2})?((?(d{3}))?)?(d{3})(d{2})(d{2})$");
return String.Format("{0}-{1}-{2}",
m.Groups[m.Groups.Count-3],
m.Groups[m.Groups.Count-2],
m.Groups[m.Groups.Count-1]);
}
static void Main(string[] args)
{
Regex phone =
new Regex(@"((+d{2})?((d{3})|d{3}))?d{7}");
MatchCollection result =
phone.Matches(Console.ReadLine());
string[] numbers = new string[result.Count];
for (int i = 0; i < result.Count; i++)
Console.WriteLine( ReformatPhone(result[i].Value) );
}
}
31. Новый результат работы
программы
Входные данные:
Результат:
Номер комнаты 120 телефон 7884028 (внутренний
4028), мобильный (050)9544552
788-40-28
954-45-52
32. Еще одно применение
// Подсчет количества предложений и слов в предложении.
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
string text = "Тест. Этот текст нужен для проверки программы."
+" Это последнее предложение.";
MatchCollection sentenses = Regex.Matches(text, @"((w+)[s.])+");
Console.WriteLine("Всего в тексте предложений - {0}.", sentenses.Count);
for (int i = 0; i < sentenses.Count; i++ ) // для каждого предложения
{
Group grp = sentenses[i].Groups[1]; // выбираем вторую группу
CaptureCollection words = grp.Captures; // получаем набор слов
Console.WriteLine("В предложении {0} всего слов {1}.",i+1, words.Count);
}
}
}
((w+)[s.])+
Группа первая (номер 0)Группа вторая (номер 1)
33. Задание на дом
Самостоятельно с использованием
учебников изучить/повторить темы:
Формат регулярных выражений
Опции регулярных выражений
Ознакомится со всеми классами
пространства имен
System.Text.RegularExpressions
Проверить все примеры программ,
приведенные в лекции
Просмотреть примеры в MSDN