Макс Ширшин — Регулярные выражения

93
Школа Разработки Интерфейсов Яндекса Симферополь, 2013 Руководитель группы разработки интерфейсов Рекламной Сети Яндекса Макс Ширшин Регулярные выражения

Upload: yandex

Post on 14-Dec-2014

1.044 views

Category:

Technology


3 download

DESCRIPTION

Чем могут быть полезны регулярные выражения для разработчика интерфейсов? О каких возможностях следует знать больше? Где находятся «подводные камни» и как обойти их в различных реализациях? И, наконец, что делать, если возможностей встроенной реализации регулярных выражений недостаточно?

TRANSCRIPT

Page 1: Макс Ширшин — Регулярные выражения

Школа Разработки Интерфейсов Яндекса Симферополь, 2013

Руководитель группы разработки интерфейсов Рекламной Сети Яндекса

Макс Ширшин

Регулярные выражения

Page 2: Макс Ширшин — Регулярные выражения

Вместо предисловия

2

Page 3: Макс Ширшин — Регулярные выражения

Виды регулярных выражений

• POSIX (BRE, ERE)

• PCRE = Perl-Compatible Regular Expressions

3

Цитата из стандарта языка JavaScript:

«Вид и функциональность регулярных выражений в JavaScript реализованы по подобию подсистемы регулярных выражений в языке программирования Perl 5»

Page 4: Макс Ширшин — Регулярные выражения

4

JS-синтаксис (очень кратко)

var re = /^foo/;

Page 5: Макс Ширшин — Регулярные выражения

5

JS-синтаксис (очень кратко)

var re = /^foo/; // boolean re.test('строка');

Page 6: Макс Ширшин — Регулярные выражения

6

JS-синтаксис (очень кратко)

var re = /^foo/; // boolean re.test('строка'); // null или Array re.exec('строка');

Page 7: Макс Ширшин — Регулярные выражения

7

Из чего состоят регэкспы

Page 8: Макс Ширшин — Регулярные выражения

8

Из чего состоят регэкспы

1. Символы

Page 9: Макс Ширшин — Регулярные выражения

9

Из чего состоят регэкспы

1. Символы

2. Операции

Page 10: Макс Ширшин — Регулярные выражения

10

Из чего состоят регэкспы

1. Символы

— обычные

2. Операции

Page 11: Макс Ширшин — Регулярные выражения

11

Из чего состоят регэкспы

1. Символы

— обычные

— специальные (метасимволы)

2. Операции

Page 12: Макс Ширшин — Регулярные выражения

12

Из чего состоят регэкспы

1. Символы

— обычные

— специальные (метасимволы)

2. Операции

— квантификация

Page 13: Макс Ширшин — Регулярные выражения

13

Из чего состоят регэкспы

1. Символы

— обычные

— специальные (метасимволы)

2. Операции

— квантификация

— перечисление

Page 14: Макс Ширшин — Регулярные выражения

14

Из чего состоят регэкспы

1. Символы

— обычные

— специальные (метасимволы)

2. Операции

— квантификация

— перечисление

— группировка

Page 15: Макс Ширшин — Регулярные выражения

Метасимволы

8

Page 16: Макс Ширшин — Регулярные выражения

/./.test('foo'); // true /./.test('\r\n') // false

16

Любой символ

Page 17: Макс Ширшин — Регулярные выражения

/./.test('foo'); // true /./.test('\r\n') // false Что вы хотели на самом деле: /[\s\S]/ для JS или /./s (не работает в JS)

17

Любой символ

Page 18: Макс Ширшин — Регулярные выражения

>>> /^something$/.test('something') true

18

Границы строк

Page 19: Макс Ширшин — Регулярные выражения

>>> /^something$/.test('something') true >>> /^something$/.test('something\nbad') false

19

Границы строк

Page 20: Макс Ширшин — Регулярные выражения

>>> /^something$/.test('something') true >>> /^something$/.test('something\nbad') false >>> /^something$/m.test('something\nbad') true

20

Границы строк

Page 21: Макс Ширшин — Регулярные выражения

>>> /\ba/.test('alabama) true

21

Граница слова

Page 22: Макс Ширшин — Регулярные выражения

>>> /\ba/.test('alabama) true >>> /a\b/.test('alabama') true

22

Граница слова

Page 23: Макс Ширшин — Регулярные выражения

>>> /\ba/.test('alabama) true >>> /a\b/.test('alabama') true >>> /a\b/.test('naïve') true

23

Граница слова

Page 24: Макс Ширшин — Регулярные выражения

>>> /\ba/.test('alabama) true >>> /a\b/.test('alabama') true >>> /a\b/.test('naïve') true не-граница слова /\Ba/.test('alabama');

24

Граница слова

Page 25: Макс Ширшин — Регулярные выражения

Символьные классы

12

Page 26: Макс Ширшин — Регулярные выражения

/\s/ (инвертированный вариант /\S/)

26

Пробельные символы

Page 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

Пробельные символы

Page 28: Макс Ширшин — Регулярные выражения

/\d/ ~ цифры от 0 до 9 /\w/ ~ буквы, цифры и подчёркивание В JS не работает для русских букв! И наоборот: /\D/ ~ всё, кроме цифр /\W/ ~ всё, кроме букв и цифр

28

Буквы и цифры

Page 29: Макс Ширшин — Регулярные выражения

Пример: /[abc123]/

29

Произвольные классы символов

Page 30: Макс Ширшин — Регулярные выражения

Пример: /[abc123]/ Работают метасимволы и диапазоны: /[A-F\d]/

30

Произвольные классы символов

Page 31: Макс Ширшин — Регулярные выражения

Пример: /[abc123]/ Работают метасимволы и диапазоны: /[A-F\d]/ Можно указать несколько диапазонов: /[a-cG-M0-7]/

31

Произвольные классы символов

Page 32: Макс Ширшин — Регулярные выражения

Пример: /[abc123]/ Работают метасимволы и диапазоны: /[A-F\d]/ Можно указать несколько диапазонов: /[a-cG-M0-7]/ ВАЖНО: диапазоны берутся из Юникода. При работе с кириллическими диапазонами проверьте порядок символов в Юникоде!

32

Произвольные классы символов

Page 33: Макс Ширшин — Регулярные выражения

символ «точка» — просто точка! /[.]/.test('anything') // false

33

Произвольные классы символов

Page 34: Макс Ширшин — Регулярные выражения

символ «точка» — просто точка! /[.]/.test('anything') // false символы: \ ] - /[\\\]-]/

34

Произвольные классы символов

Page 35: Макс Ширшин — Регулярные выражения

всё, кроме a, b, c: /[^abc]/ ^ как символ: /[abc^]/

35

Инвертированные символьные классы

Page 36: Макс Ширшин — Регулярные выражения

Квантификаторы

18

Page 37: Макс Ширшин — Регулярные выражения

/bo*/.test('b') // true

37

Ноль или более, один или более

Page 38: Макс Ширшин — Регулярные выражения

/bo*/.test('b') // true /.*/.test('') // true

38

Ноль или более, один или более

Page 39: Макс Ширшин — Регулярные выражения

/bo*/.test('b') // true /.*/.test('') // true /bo+/.test('b') // false

39

Ноль или более, один или более

Page 40: Макс Ширшин — Регулярные выражения

/colou?r/.test('color'); /colou?r/.test('colour');

40

Ноль или один

Page 41: Макс Ширшин — Регулярные выражения

41

Диапазоны повторов

/bo{7}/ точно 7

Page 42: Макс Ширшин — Регулярные выражения

42

Диапазоны повторов

/bo{7}/ точно 7 /bo{2,5}/ от 2 до 5, x < y

Page 43: Макс Ширшин — Регулярные выражения

43

Диапазоны повторов

/bo{7}/ точно 7 /bo{2,5}/ от 2 до 5, x < y /bo{5,}/ 5 или более

Page 44: Макс Ширшин — Регулярные выражения

44

Диапазоны повторов

/bo{7}/ точно 7 /bo{2,5}/ от 2 до 5, x < y /bo{5,}/ 5 или более в JS не работает! /b{,5}/.test('bbbbb')

Page 45: Макс Ширшин — Регулярные выражения

var r = /a+/.exec('aaaaa');

45

Жадные (greedy) квантификаторы

Page 46: Макс Ширшин — Регулярные выражения

var r = /a+/.exec('aaaaa'); >>> r[0]

46

Жадные (greedy) квантификаторы

Page 47: Макс Ширшин — Регулярные выражения

var r = /a+/.exec('aaaaa'); >>> r[0] "aaaaa"

47

Жадные (greedy) квантификаторы

Page 48: Макс Ширшин — Регулярные выражения

var r = /a+?/.exec('aaaaa');

48

Ленивые (lazy) квантификаторы

Page 49: Макс Ширшин — Регулярные выражения

var r = /a+?/.exec('aaaaa'); >>> r[0]

49

Ленивые (lazy) квантификаторы

Page 50: Макс Ширшин — Регулярные выражения

var r = /a+?/.exec('aaaaa'); >>> r[0] "a"

50

Ленивые (lazy) квантификаторы

Page 51: Макс Ширшин — Регулярные выражения

var r = /a+?/.exec('aaaaa'); >>> r[0] "a" r = /a*?/.exec('aaaaa');

51

Ленивые (lazy) квантификаторы

Page 52: Макс Ширшин — Регулярные выражения

var r = /a+?/.exec('aaaaa'); >>> r[0] "a" r = /a*?/.exec('aaaaa'); >>> r[0]

52

Ленивые (lazy) квантификаторы

Page 53: Макс Ширшин — Регулярные выражения

var r = /a+?/.exec('aaaaa'); >>> r[0] "a" r = /a*?/.exec('aaaaa'); >>> r[0] ""

53

Ленивые (lazy) квантификаторы

Page 54: Макс Ширшин — Регулярные выражения

Группировки

24

Page 55: Макс Ширшин — Регулярные выражения

с захватом

/(boo)/.test("boo");

55

Группировки

Page 56: Макс Ширшин — Регулярные выражения

с захватом

/(boo)/.test("boo"); без захвата

/(?:boo)/.test("boo");

56

Группировки

Page 57: Макс Ширшин — Регулярные выражения

var result = /(bo)o+(b)/.exec('the booooob');

57

Группировки и конструктор RegExp

Page 58: Макс Ширшин — Регулярные выражения

var result = /(bo)o+(b)/.exec('the booooob'); >>> RegExp.$1 "bo"

58

Группировки и конструктор RegExp

Page 59: Макс Ширшин — Регулярные выражения

var result = /(bo)o+(b)/.exec('the booooob'); >>> RegExp.$1 "bo" >>> RegExp.$2 "b"

59

Группировки и конструктор RegExp

Page 60: Макс Ширшин — Регулярные выражения

var result = /(bo)o+(b)/.exec('the booooob'); >>> RegExp.$1 "bo" >>> RegExp.$2 "b" >>> RegExp.$9 ""

60

Группировки и конструктор RegExp

Page 61: Макс Ширшин — Регулярные выражения

var result = /(bo)o+(b)/.exec('the booooob'); >>> RegExp.$1 "bo" >>> RegExp.$2 "b" >>> RegExp.$9 "" >>> RegExp.$10 undefined

61

Группировки и конструктор RegExp

Page 62: Макс Ширшин — Регулярные выражения

var result = /(bo)o+(b)/.exec('the booooob'); >>> RegExp.$1 "bo" >>> RegExp.$2 "b" >>> RegExp.$9 "" >>> RegExp.$10 undefined >>> RegExp.$0 undefined

62

Группировки и конструктор RegExp

Page 63: Макс Ширшин — Регулярные выражения

/((foo) (b(a)r))/

63

Порядок нумерации группировок

Page 64: Макс Ширшин — Регулярные выражения

/((foo) (b(a)r))/ $1 ( ) foo bar

64

Порядок нумерации группировок

Page 65: Макс Ширшин — Регулярные выражения

/((foo) (b(a)r))/ $1 ( ) foo bar $2 ( ) foo

65

Порядок нумерации группировок

Page 66: Макс Ширшин — Регулярные выражения

/((foo) (b(a)r))/ $1 ( ) foo bar $2 ( ) foo $3 ( ) bar

66

Порядок нумерации группировок

Page 67: Макс Ширшин — Регулярные выражения

/((foo) (b(a)r))/ $1 ( ) foo bar $2 ( ) foo $3 ( ) bar $4 ( ) a

67

Порядок нумерации группировок

Page 68: Макс Ширшин — Регулярные выражения

var r = /best(?= match)/.exec('best match');

68

Lookahead

Page 69: Макс Ширшин — Регулярные выражения

var r = /best(?= match)/.exec('best match'); >>> !!r true

69

Lookahead

Page 70: Макс Ширшин — Регулярные выражения

var r = /best(?= match)/.exec('best match'); >>> !!r true >>> r[0] "best"

70

Lookahead

Page 71: Макс Ширшин — Регулярные выражения

var r = /best(?= match)/.exec('best match'); >>> !!r true >>> r[0] "best" >>> /best(?! match)/.test('best match') false

71

Lookahead

Page 72: Макс Ширшин — Регулярные выражения

Перечисление

30

Page 73: Макс Ширшин — Регулярные выражения

/red|green|blue light/ /(red|green|blue) light/ >>> /var a(;|$)/.test('var a') true

73

Логическое «или»

Page 74: Макс Ширшин — Регулярные выражения

true /(red|green) apple is \1/.test('red apple is red') true /(red|green) apple is \1/.test('green apple is green')

74

Backreferences (обратные ссылки)

Page 75: Макс Ширшин — Регулярные выражения

Представление символов

32

Page 76: Макс Ширшин — Регулярные выражения

\x09 === \t (не Unicode, для ASCII/ANSI) \u20AC === € (для Unicode)

76

Представление символов

Page 77: Макс Ширшин — Регулярные выражения

\x09 === \t (не Unicode, для ASCII/ANSI) \u20AC === € (для Unicode) обратный slash убирает специальное значение у символа /\(\)/.test('()') // true /\\n/.test('\\n') // true

77

Представление символов

Page 78: Макс Ширшин — Регулярные выражения

\x09 === \t (не Unicode, для ASCII/ANSI) \u20AC === € (для Unicode) обратный slash убирает специальное значение у символа /\(\)/.test('()') // true /\\n/.test('\\n') // true иногда верно и обратное /\f/.test('f') // false!

78

Представление символов

Page 79: Макс Ширшин — Регулярные выражения

Флаги

34

Page 80: Макс Ширшин — Регулярные выражения

g i m s x

80

Флаги в регулярных выражениях

Page 81: Макс Ширшин — Регулярные выражения

g i m s x global match

81

Флаги в регулярных выражениях

Page 82: Макс Ширшин — Регулярные выражения

g i m s x global match ignore case

82

Флаги в регулярных выражениях

Page 83: Макс Ширшин — Регулярные выражения

g i m s x global match ignore case multiline matching for ^ and $

83

Флаги в регулярных выражениях

Page 84: Макс Ширшин — Регулярные выражения

g i m s x global match ignore case multiline matching for ^ and $ нет поддержки в JS для: string as single line extend pattern

84

Флаги в регулярных выражениях

Page 85: Макс Ширшин — Регулярные выражения

/(?i)foo/ /(?i-m)bar$/ /(?i-sm).x$/ /(?i)foo(?-i)bar/ Не все реализации поддерживают переключение флагов внутри regexp. JS при таком синтаксисе включает флаги на весь regexp сразу и не даёт менять.

85

Альтернативный синтаксис для флагов

Page 86: Макс Ширшин — Регулярные выражения

RegExp в JavaScript

86

Page 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

Методы

Page 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

Методы

Page 89: Макс Ширшин — Регулярные выражения

// ПЛОХО 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

RegExp injection

Page 90: Макс Ширшин — Регулярные выражения

Что почитать

90

Page 91: Макс Ширшин — Регулярные выражения

91

В интернете: javascript.ru/basic/regular-expression

Mastering Regular Expressions

O'Reilly Media

Книга:

Page 92: Макс Ширшин — Регулярные выражения

Вопросы?

92

Page 93: Макс Ширшин — Регулярные выражения

Руководитель группы разработки интерфейсов Рекламной Сети Яндекса

[email protected]

@ingdir

Макс Ширшин