2013 09 21 регулярные выражения

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

Transcript of 2013 09 21 регулярные выражения

Page 1: 2013 09 21 регулярные выражения

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

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

Макс  Ширшин  

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

Page 2: 2013 09 21 регулярные выражения

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

2  

Page 3: 2013 09 21 регулярные выражения

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

•  POSIX  (BRE,  ERE)  

•  PCRE  =  Perl-­‐CompaYble  Regular  Expressions  

3  

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

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

Page 4: 2013 09 21 регулярные выражения

4  

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

var  re  =  /^foo/;                                                                                                                                                        

Page 5: 2013 09 21 регулярные выражения

5  

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

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

Page 6: 2013 09 21 регулярные выражения

6  

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

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

Page 7: 2013 09 21 регулярные выражения

7  

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

                 

                 

                                                     

                   

                             

                           

                         

Page 8: 2013 09 21 регулярные выражения

8  

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

1.  Символы  

                 

                                                     

                   

                             

                           

                         

Page 9: 2013 09 21 регулярные выражения

9  

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

1.  Символы  

                 

                                                     

2.  Операции  

                             

                           

                         

Page 10: 2013 09 21 регулярные выражения

10  

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

1.  Символы  

—  обычные  

                                                     

2.  Операции  

                             

                           

                         

Page 11: 2013 09 21 регулярные выражения

11  

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

1.  Символы  

—  обычные  

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

2.  Операции  

                             

                           

                         

Page 12: 2013 09 21 регулярные выражения

12  

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

1.  Символы  

—  обычные  

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

2.  Операции  

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

                           

                         

Page 13: 2013 09 21 регулярные выражения

13  

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

1.  Символы  

—  обычные  

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

2.  Операции  

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

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

                         

Page 14: 2013 09 21 регулярные выражения

14  

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

1.  Символы  

—  обычные  

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

2.  Операции  

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

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

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

Page 15: 2013 09 21 регулярные выражения

Метасимволы  

8  

Page 16: 2013 09 21 регулярные выражения

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

16  

Любой  символ  

Page 17: 2013 09 21 регулярные выражения

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

17  

Любой  символ  

Page 18: 2013 09 21 регулярные выражения

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

18  

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

Page 19: 2013 09 21 регулярные выражения

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

19  

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

Page 20: 2013 09 21 регулярные выражения

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

20  

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

Page 21: 2013 09 21 регулярные выражения

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

21  

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

Page 22: 2013 09 21 регулярные выражения

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

22  

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

Page 23: 2013 09 21 регулярные выражения

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

23  

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

Page 24: 2013 09 21 регулярные выражения

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

24  

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

Page 25: 2013 09 21 регулярные выражения

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

12  

Page 26: 2013 09 21 регулярные выражения

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

                                                                                                                                                                                                                                                               

                                                                                                                                                                                       

26  

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

Page 27: 2013 09 21 регулярные выражения

/\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: 2013 09 21 регулярные выражения

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

28  

Буквы  и  цифры  

Page 29: 2013 09 21 регулярные выражения

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

                                                                                                                                                             

29  

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

Page 30: 2013 09 21 регулярные выражения

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

                                                                                                                                                             

30  

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

Page 31: 2013 09 21 регулярные выражения

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

                                                                                                                                                             

31  

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

Page 32: 2013 09 21 регулярные выражения

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

32  

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

Page 33: 2013 09 21 регулярные выражения

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

33  

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

Page 34: 2013 09 21 регулярные выражения

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

34  

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

Page 35: 2013 09 21 регулярные выражения

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

35  

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

Page 36: 2013 09 21 регулярные выражения

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

18  

Page 37: 2013 09 21 регулярные выражения

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

37  

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

Page 38: 2013 09 21 регулярные выражения

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

38  

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

Page 39: 2013 09 21 регулярные выражения

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

39  

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

Page 40: 2013 09 21 регулярные выражения

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

40  

Ноль  или  один  

Page 41: 2013 09 21 регулярные выражения

41  

Диапазоны  повторов  /bo{7}/        точно  7                                                                                                                                                                                                                      

Page 42: 2013 09 21 регулярные выражения

42  

Диапазоны  повторов  /bo{7}/        точно  7    /bo{2,5}/    от  2  до  5,  x  <  y                                                                                                                                                          

Page 43: 2013 09 21 регулярные выражения

43  

Диапазоны  повторов  /bo{7}/        точно  7    /bo{2,5}/    от  2  до  5,  x  <  y            /bo{5,}/      5  или  более                                                                                                

Page 44: 2013 09 21 регулярные выражения

44  

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

Page 45: 2013 09 21 регулярные выражения

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

45  

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

Page 46: 2013 09 21 регулярные выражения

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

46  

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

Page 47: 2013 09 21 регулярные выражения

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

47  

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

Page 48: 2013 09 21 регулярные выражения

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

48  

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

Page 49: 2013 09 21 регулярные выражения

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

49  

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

Page 50: 2013 09 21 регулярные выражения

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

50  

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

Page 51: 2013 09 21 регулярные выражения

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

51  

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

Page 52: 2013 09 21 регулярные выражения

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

52  

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

Page 53: 2013 09 21 регулярные выражения

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

53  

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

Page 54: 2013 09 21 регулярные выражения

Группировки  

24  

Page 55: 2013 09 21 регулярные выражения

с  захватом  /(boo)/.test("boo");                                                                                

55  

Группировки  

Page 56: 2013 09 21 регулярные выражения

с  захватом  /(boo)/.test("boo");    без  захвата  /(?:boo)/.test("boo");    

56  

Группировки  

Page 57: 2013 09 21 регулярные выражения

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

                                                                                                               

57  

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

Page 58: 2013 09 21 регулярные выражения

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

                                                                                                               

58  

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

Page 59: 2013 09 21 регулярные выражения

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

                                                                                                               

59  

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

Page 60: 2013 09 21 регулярные выражения

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

60  

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

Page 61: 2013 09 21 регулярные выражения

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

61  

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

Page 62: 2013 09 21 регулярные выражения

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: 2013 09 21 регулярные выражения

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

63  

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

Page 64: 2013 09 21 регулярные выражения

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

64  

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

Page 65: 2013 09 21 регулярные выражения

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

65  

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

Page 66: 2013 09 21 регулярные выражения

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

66  

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

Page 67: 2013 09 21 регулярные выражения

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

67  

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

Page 68: 2013 09 21 регулярные выражения

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

68  

Lookahead  

Page 69: 2013 09 21 регулярные выражения

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

69  

Lookahead  

Page 70: 2013 09 21 регулярные выражения

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

70  

Lookahead  

Page 71: 2013 09 21 регулярные выражения

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

71  

Lookahead  

Page 72: 2013 09 21 регулярные выражения

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

30  

Page 73: 2013 09 21 регулярные выражения

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

73  

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

Page 74: 2013 09 21 регулярные выражения

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: 2013 09 21 регулярные выражения

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

32  

Page 76: 2013 09 21 регулярные выражения

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

                                                                                                                                                                                                                                                               

76  

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

Page 77: 2013 09 21 регулярные выражения

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

77  

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

Page 78: 2013 09 21 регулярные выражения

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

78  

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

Page 79: 2013 09 21 регулярные выражения

Флаги  

34  

Page 80: 2013 09 21 регулярные выражения

g  i  m  s  x                                                                                                                                                                                                                                                                    

80  

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

Page 81: 2013 09 21 регулярные выражения

g  i  m  s  x            global  match                                                                                                                                                                                                                              

81  

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

Page 82: 2013 09 21 регулярные выражения

g  i  m  s  x            global  match  ignore  case                                                                                                                                                                                                    

82  

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

Page 83: 2013 09 21 регулярные выражения

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

83  

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

Page 84: 2013 09 21 регулярные выражения

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

84  

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

Page 85: 2013 09 21 регулярные выражения

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

85  

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

Page 86: 2013 09 21 регулярные выражения

RegExp  в  JavaScript  

86  

Page 87: 2013 09 21 регулярные выражения

экземпляры  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: 2013 09 21 регулярные выражения

экземпляры  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: 2013 09 21 регулярные выражения

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

Page 90: 2013 09 21 регулярные выражения

Что  почитать  

90  

Page 91: 2013 09 21 регулярные выражения

91  

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

Mastering  Regular  Expressions  O'Reilly  Media  

Книга:  

Page 92: 2013 09 21 регулярные выражения

Что  поделать  

92  

Page 93: 2013 09 21 регулярные выражения

93  

Кроссворд  из  регулярных  выражений      clck.ru/8pyrR  clck.ru/8pyrm  

Page 94: 2013 09 21 регулярные выражения

Вопросы?  

94  

Page 95: 2013 09 21 регулярные выражения

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

ingdir@yandex-­‐team.ru  

@ingdir  

Макс  Ширшин