Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Проверка на десятки и единицы. Подробные регулярные выражения




Проверка на десятки и единицы

Теперь давайте расширим регулярное выражение чтобы включить десятки и единицы. Этот пример показывает проверку на десятки.

> > > pattern = '^M? M? M? (CM|CD|D? C? C? C? )(XC|XL|L? X? X? X? )$'
> > > re. search(pattern, 'MCMXL') ①
< _sre. SRE_Match object at 0x008EEB48>
> > > re. search(pattern, 'MCML') ②
< _sre. SRE_Match object at 0x008EEB48>
> > > re. search(pattern, 'MCMLX') ③
UNIQae610d7ca506639d-nowiki-0000004F-QINU
> > > re. search(pattern, 'MCMLXXX') ④
UNIQae610d7ca506639d-nowiki-00000050-QINU
> > > re. search(pattern, 'MCMLXXXX') ⑤
> > >

  • ① Тут патерн совпадает с началом строки, потом с первым опциональным символом М, потом CM, потом XL, потом с концом строки. Вспомните что синтаксис (A|B|C) означает «совпасть только с одним оз символов A, B или C» У нас совпадает XL, и мы игнорируем XC и L? X? X? X? , а после этого переходим к концу строки. MCMXL это римское представление числа 1940.
  • ② Тут патерн совпадает с началом строки, потом с первым опциональным символом М, потом CM, потом с L? X? X? X?. Из L? X? X? X? Совпадает L и пропускает три опциональных символа X. После этого переходит к концу строки. MCML это римское представление числа 1950.
  • ③ Тут патерн совпадает с началом строки, потом с первым опциональным символом М, потом CM, потом с опциональным L и первым опциональным X, пропуская второй и третий опциональные символы X, после этого переходит к концу строки. MCMLX это римское представление числа 1960.
  • ④ Тут патерн совпадает с началом строки, потом с первым опциональным символом М, потом CM, потом с опциональным L и всеми тремя опциональными символами X, после этого переходит к концу строки. MCMLXXX это римское представление числа 1980.
  • ⑤ Тут патерн совпадает с началом строки, потом с первым опциональным символом М, потом CM, потом с опциональным L и всеми тремя опциональными символами X, после этого не совпадает с концом строки, так как есть ещё один символ X, таким образом патерн не срабатывает и возвращает None. MCMLXXXX это недопустимое римское число.


(A|B) совпадает либо с A либо с B.

Для описания единиц подходит тот же патерн. Я уменьшу детализацию и покажу конечный результат.

> > > pattern = '^M? M? M? (CM|CD|D? C? C? C? )(XC|XL|L? X? X? X? )(IX|IV|V? I? I? I? )$'

Итак как это будет выглядеть используя альтернативный синтаксис {n, m}? Этот пример показывает новый синтаксис.

> > > pattern = '^M{0, 3}(CM|CD|D? C{0, 3})(XC|XL|L? X{0, 3})(IX|IV|V? I{0, 3})$'
> > > re. search(pattern, 'MDLV') ①
UNIQae610d7ca506639d-nowiki-00000053-QINU
> > > re. search(pattern, 'MMDCLXVI') ②
UNIQae610d7ca506639d-nowiki-00000054-QINU
> > > re. search(pattern, 'MMMDCCCLXXXVIII') ③
UNIQae610d7ca506639d-nowiki-00000055-QINU
> > > re. search(pattern, 'I') ④
UNIQae610d7ca506639d-nowiki-00000056-QINU

  • ① Тут патерн совпадает с началом строки, потом с одним из трёх возможных символов М, потом D? C{0, 3}. Из них совпадает только опциональное D и ни один из опциональных C. Далее совпадает опциональное L из L? X{0, 3} и ни один из трёх опциональных X. После совпадает с V из V? I{0, 3} и ни с одним из трёх опциональных I и наконец с концом строки. MDLV это римское представление числа 1555.
  • ② Тут патерн совпадает с началом строки, потом с двумя из трёх возможных символов М, потом D и один опциональный C из D? C{0, 3}. Потом L? X{0, 3} с L и один из трёх возможных X, потом V? I{0, 3} с V и одним из трёх I, потом с концом строки. MMDCLXVI это римское представление числа 2666.
  • ③ Тут патерн совпадает с началом строки, потом с тремя из трёх M, потом D и C из D? C{0, 3}, потом L? X{0, 3} с L и три из трёх X, потом V? I{0, 3} с V и тремя из трёх I, потом конец строки. MMMDCCCLXXXVIII это римское представление числа 3888, и это максимально длинное римское число которое можно записать без расширенного синтаксиса.
  • ④ Смотрите внимательно. (Я чувствую себя магом, «Смотрите внимательно детки, сейчас кролик вылезет из моей шляпы; )» Тут совпадает начало строки, ни один из трёх М, потом D? C{0, 3} пропускает опциональный D и три опциональных C, потом L? X{0, 3} пропуская опциональный L и три опциональных X, потом V? I{0, 3} пропуская опциональный V и один из трёх опциональных I. Потом конец строки. Стоп, фуф.


Если вы следовали всему и поняли с первой попытки, значит у вас получается лучше чем у меня. Теперь представьте что вы пытаетесь разобраться в чьих то регулярных выражениях в важной функции в рамках огромной программы. Или например представьте что вы возвращаетесь к собственной программе через несколько месяцев. Я делал это и это не слишком приятное зрелище.

А сейчас давайте исследуем альтернативный синтаксис, который позволит легче выполнять поддержку ваших выражений.

Подробные регулярные выражения

До сих пор вы имели дело с тем что я называю «компактными» регулярными выражениями. Как вы могли заметить они трудны для прочтения, даже если вы понимаете что они делают. Нет гарантии что вы сможете разобраться в них спустя шесть месяцев. Что вам действительно необходимо так это вложенная документация

Python позволяет вам сделать это при помощи подробных регулярных выражений. Подробные регулярные выражения отличаются от компактных двумя способами:

 

  • Пустые строки игнорируются, пробелы, табы и возвраты каретки не совпадают соответственно. Они вообще не совпадают. (Если вы хотите совпадения с пробелом в подробном регулярном выражении, вам необходимо поставить бэкслэш перед ним. )
  • Комментарии игнорируются. Комментарий в подробном регулярном выражении такой же как и комментарий в коде Python: он начинается с символа # и действует до конца строки. В этом случае этото комментарий это комментарий внутри многострочной строки, но он работает также как и простой.

Пример сделает это более понятным. Давайте перепроверим компактное регулярное выражение с которым мы работали и создадим подробное регулярное выражение. Этот пример показан ниже.

> > > pattern = '''
^ # начало строки
M{0, 3} # тысячи - 0 до 3 M
(CM|CD|D? C{0, 3}) # сотни — 900 (CM), 400 (CD), 0-300 (0 до 3 C),
# или 500-800 (D, с последующими от 0 до 3 C)
(XC|XL|L? X{0, 3}) # десятки - 90 (XC), 40 (XL), 0-30 (0 до 3 X),
# или 50-80 (L, с последующими от 0 до 3 X)
(IX|IV|V? I{0, 3}) # единицы - 9 (IX), 4 (IV), 0-3 (0 до 3 I),
# или 5-8 (V, с последующими от 0 до 3 I)
$ # конец строки
'''
> > > re. search(pattern, 'M', re. VERBOSE) ①
UNIQae610d7ca506639d-nowiki-00000058-QINU
> > > re. search(pattern, 'MCMLXXXIX', re. VERBOSE) ②
UNIQae610d7ca506639d-nowiki-00000059-QINU
> > > re. search(pattern, 'MMMDCCCLXXXVIII', re. VERBOSE) ③
< _sre. SRE_Match object at 0x008EEB48>
> > > re. search(pattern, 'M') ④

  • ① Главное что надо запомнить, это то что необходимо добавлять экстра аргументы для работы с ними: re. VERBOSE это константа определённая в модуле re которая служит сигналом что патерн должен быть использован как подробное регулярное выражение. Как вы можете видеть, этот патерн содержит большое количество пустых строк. (и все они игнорируются), а также несколько комментариев (которые игнорируются также). Если мы игнорируем комментарии и пустые строки, то получается то же самое регулярное выражение что и в предыдущем примере, но в гораздо более читабельном виде.
  • ② Здесь совпадает начало строки, потом одно и трёх возможных M, потом CM, потом L и три из возможных X, потом IX, потом конец строки.
  • ③ Здесь совпадает начало строки, потом три из трёх возможных M, потом D и три из возможных трёх C, потом L и три из трёх возможных X, потом V и три из трёх возможных I, потом конец строки.
  • ④ Тут не совпадает. Почему? Так как отсутствует флаг re. VERBOSE и функция re. search рассматривает патерн как компактное регулярное выражение, с значащими пробелами и символами #. Python не может автоматически определить является ли регулярное выражение подробным или нет. Python рассматривает каждое регулярное выражение как компактное до тех пор пока вы не укажете что оно подробное.

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...