Итоги. Замыкания и генераторы. Погружение. Я знаю, используем регулярные выражения!
Итоги
Это всего лишь верхушка айсберга того что могут делать регулярные выражения. Другими словами, даже если вы полностью ошеломлены ими сейчас, поверьте мне, вы ещё ничего не видели.
Вы должны быть сейчас умелыми в следующей технике:
^ совпадение с началом строки.
$ совпадение с концом строки.
\b совпадает с границей слова.
\d совпадает с цифрой.
\D совпадает с не цифрой.
x? совпадает с опциональным символом x (другими словами ноль или один символов x).
x* совпадает с ноль или более x.
x+ совпадает с один или более x.
x{n, m} совпадает с x не менее n раз, но не более m раз.
(a|b|c) совпадает с a или b или c.
(x) группа для запоминания. Вы можете получить значение используя метод groups() на объекте который возвращает re. search.
Регулярные выражения экстремально мощный инструмент, но они не всегда корректный способ для решения любой проблемы. Вы должны изучить побольше о них чтобы разобраться когда они являются подходящими для решения проблемы, так как иногда они могут добавить больше проблем чем решить
Замыкания и генераторы
Погружение
По причинам, превосходящим всяческое понимание, я всегда восхищался языками. Не языками программирования. Хотя да, ими, а также языками естественными. Возьмем, к примеру, английский. Английский язык — это шизофренический язык, который заимствует слова из немецкого, французского, испанского и латинского языков (не говоря уже об остальных). Откровенно говоря, «заимствует» — неуместное слово; он их скорее «ворует». Или, возможно, «ассимилирует» — как Борги. Да, хороший вариант.
«
| Мы Борги. Ваши лингвистические и этимологические особенности станут нашими. Сопротивление бесполезно.
| »
|
В этой главе вы узнаете о существительных во множественном числе. Также вы узнаете о функциях, которые возвращают другие функции, о сложных регулярных выражениях и генераторах. Но сначала давайте поговорим о том, как образуются существительные во множественном числе. (Если вы не читали раздел посвященный регулярным выражениям, сейчас — самое время. Материал этого раздела подразумевает, что вы понимаете основы регулярных выражений, и довольно быстро перейдете к их нетривиальному использованию).
Если вы выросли в англоязычной стране или изучали английский в формальной школьной обстановке, вы, вероятно, знакомы с основными правилами:
- Если слово заканчивается буквами S, X или Z, следует добавить ES. Bass становится basses, fax становится faxes, а waltz — waltzes.
- Если слово заканчивается звонкой H, следует добавить ES; если заканчивается глухой H, то нужно просто добавить S. Что такое звонкая H? Это такая, которая вместе с другими буквами объединяется в звук, который вы можете расслышать. Соответственно, coach становится coaches, и rash становится rashes, потому что вы слышите звуки CH и SH, когда произносите эти слова. Но cheetah становится cheetahs, потому что H здесь глухая.
- Если слово заканчивается на Y, которая читается как I, то замените Y на IES; если Y объединена с гласной и звучит как-то по-другому, то просто добавьте S. Так что vacancy становится vacancies, но day становится days.
- Если ни одно из правил не подходит, просто добавьте S и надейтесь на лучшее.
(Я знаю, существует множество исключений. Man становится men, а woman — women, но human становится humans. Mouse — mice, а louse — lice, но house во множественной числе — houses. Knife становится knives, а wife становится wives, но lowlife становится lowlifes. И не заставляйте меня вглядываться в слова, которые не изменяются во множественном числе, как например sheep, deer или haiku).
Остальные языки, конечно, совершенно другие.
Давайте разработаем библиотеку на Python, которая автоматически образует множественное число английского слова. Мы начнем с этих четырех правил, но не забывайте, что вам неизбежно понадобится добавлять еще.
Я знаю, используем регулярные выражения!
Итак, вы смотрите на слова, и, по крайней мере в английском, это означает, что вы смотрите на последовательности символов. У вас есть правила, которые говорят, что нужно искать разные комбинации символов, потом совершать с ними различные действия. Похоже, это работа для регулярных выражений!
import re
def plural(noun):
if re. search('[sxz]$', noun): UNIQd2f4acf57a9a5326-ref-00000003-QINU
return re. sub('$', 'es', noun) UNIQd2f4acf57a9a5326-ref-00000006-QINU
elif re. search('[^aeioudgkprt]h$', noun):
return re. sub('$', 'es', noun)
elif re. search('[^aeiou]y$', noun):
return re. sub('y$', 'ies', noun)
else:
return noun + 's'
- ↑ Это регулярное выражение, но оно использует синтаксис, который вы не видели в главе Регулярные Выражения. Квадратные скобки означают «найти совпадения ровно с одним из этих символов». Поэтому [sxz] означает «s или x, или z», но только один из них. Символ $ должен быть знаком вам. Он ищет совпадения с концом строки. Все регулярное выражение проверяет, заканчивается ли noun на s, x или z.
- ↑ Упомянутая функция re. sub() производит замену подстроки на основе регулярного выражения.
Рассмотрим замену с помощью регулярного выражения внимательнее.
> > > import re
> > > re. search('[abc]', 'Mark') ①
< _sre. SRE_Match object at 0x001C1FA8>
> > > re. sub('[abc]', 'o', 'Mark') ②
'Mork'
> > > re. sub('[abc]', 'o', 'rock') ③
'rook'
> > > re. sub('[abc]', 'o', 'caps') ④
'oops'
- Содержит ли строка Mark символы a, b или c? Да, содержит a.
- Отлично, теперь ищем a, b или c и заменяем на o. Mark становится Mork.
- Та же функция превращает rock в rook.
- Вы могли подумать, что этот код caps преобразует в oaps, но он этого не делает. re. sub заменяет все совпадения, а не только первое найденное. Так что, данное регулярное выражение превратит caps в oops, потому что оба символа c и a заменяются на o.
Вернемся снова к функции plural()…
def plural(noun):
if re. search('[sxz]$', noun):
return re. sub('$', 'es', noun) ①
elif re. search('[^aeioudgkprt]h$', noun): ②
return re. sub('$', 'es', noun)
elif re. search('[^aeiou]y$', noun): ③
return re. sub('y$', 'ies', noun)
else:
return noun + 's'
- Здесь вы заменяете конец строки (найденный с помощью символа $) на строку es. Другими словами, добавляете es к строке. Вы могли бы совершить то же самое с помощью конкатенации строк, например, как noun + 'es', но я предпочел использовать регулярные выражения для каждого правила, по причинам которые станут ясны позже.
- Взгляните-ка, это регулярное выражение содержит кое-что новое. Символ ^ в качестве первого символа в квадратных скобках имеет особый смысл: отрицание. [^abc] означает «любой отдельный символ кроме a, b или c». Так что [^aeioudgkprt] означает любой символ кроме a, e, i, o, u, d, g, k, p, r или t. Затем за этим символом должен быть символ h, следом за ним — конец строки. Вы ищете слова, заканчивающиеся на H, которую можно услышать.
- То же самое здесь: найти слова, которые заканчиваются на Y, в которых символ перед Y — не a, e, i, o или u. Вы ищете слова, заканчивающиеся на Y, которая звучит как I.
Давайте внимательнее рассмотрим регулярные выражения с участием отрицания.
> > > import re
> > > re. search('[^aeiou]y$', 'vacancy') ①
< _sre. SRE_Match object at 0x001C1FA8>
> > > re. search('[^aeiou]y$', 'boy') ②
> > >
> > > re. search('[^aeiou]y$', 'day')
> > >
> > > re. search('[^aeiou]y$', 'pita') ③
> > >
- vacancy подходит, потому что оно заканчивается на cy, и c — не a, e, i, o или u.
- boy не подходит, потому что оно заканчивается на oy, а вы конкретно указали, что символ перед y не может быть o. day не подходит, потому что он заканчивается на ay.
- pita не подходит, потому что оно не заканчивается на y.
> > > re. sub('y$', 'ies', 'vacancy') ①
'vacancies'
> > > re. sub('y$', 'ies', 'agency') 'agencies'
> > > re. sub('([^aeiou])y$', r'\1ies', 'vacancy') ②
'vacancies'
- Это регулярное выражение преобразует vacancy в vacancies, а agency — в agencies, что вам и нужно. Заметьте, что оно бы преобразовало boy в boies, но этого в функции никогда не произойдет, потому что вы сначала сделали re. search с целью выяснить, следует ли делать re. sub.
- Замечу заодно, что возможно объединить эти два регулярных выражения (одно чтобы выяснить применяется ли правило, а другое чтобы собственно его применить) в одно регулярное выражение. Вот так выглядел бы результат. Большая часть должна быть вам знакома: вы используете запоминаемую группу, о которой вы узнали из Учебный пример: Разбор телефонного номера. Группа используется чтобы запомнить символ перед y. Затем в подстановочной строке, вы используете новый синтаксис, \1, который означает «эй, та первая группа, которую ты запомнил? положи ее сюда». Таким образом, вы помните c перед y; когда вы делаете подстановку, вы ставите c на место c, и ies на место y. (Если у вас более одной запоминаемой группы, можете использовать \2 и \3 и так далее. )
Замены с использованием регулярных выражений являются чрезвычайно мощным инструментом, а синтаксис \1 делает их еще более мощным. Но вся операция, объединенная в одно регулярное выражение, также становится сложной для чтения, кроме того такой способ не соотносится напрямую с тем, как вы изначально описали правила формирования множественного числа. Изначально вы спроектировали правила в форме «если слово заканчивается на S, X или Z, то добавьте ES». А если вы смотрите на функцию, то у вас — две строки кода, которые говорят «если слово заканчивается на S, X или Z, то добавьте ES». Еще ближе к оригинальному варианту приблизиться никак не получится.
Воспользуйтесь поиском по сайту: