Чем могут быть полезны регулярные выражения для разработчика интерфейсов? О каких возможностях следует знать больше? Где находятся «подводные камни» и как обойти их в различных реализациях? И, наконец, что делать, если возможностей встроенной реализации регулярных выражений недостаточно?
3. Виды регулярных выражений
• POSIX (BRE, ERE)
• PCRE = Perl-Compatible Regular Expressions
Цитата из стандарта языка JavaScript:
«Вид и функциональность регулярных
выражений в JavaScript реализованы
по подобию подсистемы регулярных
выражений в языке программирования Perl 5»
3
27. Пробельные символы
/s/ (инвертированный вариант /S/)
FF:
t n v f r u0020 u00a0
u1680 u180e u2000 u2001 u2002 u2003 u2004
u2005 u2006 u2007 u2008 u2009 u200a u2028
u2029 u202f u205f u3000
Chrome 19, IE 9:
как в FF 12 и ещё ufeff
IE 7, 8 :-(
только:
t n v f r u0020
27
28. Буквы и цифры
/d/ ~ цифры от 0 до 9
/w/ ~ буквы, цифры и подчёркивание
В JS не работает для русских букв!
И наоборот:
/D/ ~ всё, кроме цифр
/W/ ~ всё, кроме букв и цифр
28
31. Произвольные классы символов
Пример:
/[abc123]/
Работают метасимволы и диапазоны:
/[A-Fd]/
Можно указать несколько диапазонов:
/[a-cG-M0-7]/
31
32. Произвольные классы символов
Пример:
/[abc123]/
Работают метасимволы и диапазоны:
/[A-Fd]/
Можно указать несколько диапазонов:
/[a-cG-M0-7]/
ВАЖНО: диапазоны берутся из Юникода.
При работе с кириллическими диапазонами
проверьте порядок символов в Юникоде!
32
74. Backreferences
(обратные ссылки)
true
/(red|green) apple is 1/.test('red apple is red')
true
/(red|green) apple is 1/.test('green apple is green')
74
77. Представление символов
x09 === t (не Unicode, для ASCII/ANSI)
u20AC === € (для Unicode)
обратный slash убирает специальное
значение у символа
/()/.test('()') // true
/n/.test('n') // true
77
78. Представление символов
x09 === t (не Unicode, для ASCII/ANSI)
u20AC === € (для Unicode)
обратный slash убирает специальное
значение у символа
/()/.test('()') // true
/n/.test('n') // true
иногда верно и обратное
/f/.test('f') // false!
78
83. Флаги в регулярных выражениях
g i m s x
global match
ignore case
multiline matching for ^ and $
83
84. Флаги в регулярных выражениях
g i m s x
global match
ignore case
multiline matching for ^ and $
нет поддержки в JS для:
string as single line
extend pattern
84
85. Альтернативный синтаксис
для флагов
/(?i)foo/
/(?i-m)bar$/
/(?i-sm).x$/
/(?i)foo(?-i)bar/
Не все реализации поддерживают
переключение флагов внутри regexp.
JS при таком синтаксисе включает флаги на
весь regexp сразу и не даёт менять.
85
87. Методы
экземпляры RegExp:
/regexp/.exec('строка')
null или массив ['всё совпадение', $1, $2, ...]
/regexp/.test('строка')
false или true
экземпляры String:
'str'.match(/regexp/)
'str'.match('w{1,3}')
- эквивалент /regexp/.exec, если нет флага g;
- массив всех совпадений по строке, если есть флаг g
(внутренние группировки игнорируются)
'str'.search(/regexp/)
'str'.search('w{1,3}')
позиция первого совпадения или -1
87
88. Методы
экземпляры String:
'str'.replace(/old/, 'new');
В строке замены поддерживаются следующие спецсимволы:
$$ вставляет значок доллара "$"
$& подстрока, совпавшая с регэкспом
$` подстрока до $&
$' подстрока после $&
$1, $2, $3 и т.д.: cтрока, совпавшая с соответствующей
скобочной группировкой
'str'.replace(/(r)(e)gexp/g,
function(matched, $1, $2, offset, sourceString) {
// чем заменить matched на этом шаге?
return 'замена';
});
88
89. RegExp injection
// ПЛОХО
var re = new RegExp('^' + userInput + '$');
var userInput = '[abc]';
// ХОРОШО
RegExp.escape = function(text) {
return text.replace(/[-[]{}()*+?.,^$|#s]/g, "$&");
};
var re = new RegExp('^' + RegExp.escape(userInput) + '$');
89