Главная страница
Навигация по странице:

  • Поиск удвоенных символов в строковых значениях

  • Модификация задаваемых регулярными выражениями шаблонов в многострочном строковом значении

  • однострочники пайтон. Однострочники Python лаконичный и содержательный код by Кристи. Однострочники


    Скачать 4.44 Mb.
    НазваниеОднострочники
    Анкороднострочники пайтон
    Дата22.04.2022
    Размер4.44 Mb.
    Формат файлаpdf
    Имя файлаОднострочники Python лаконичный и содержательный код by Кристи.pdf
    ТипКнига
    #490720
    страница17 из 21
    1   ...   13   14   15   16   17   18   19   20   21
    202
    Глава 5. Регулярные выражения '''
    True
    True
    False
    False
    False
    False
    '''
    Обратите внимание, что шестая из строк результата демонстрирует: время
    99:99
    более не считается допустимыми входными данными. Этот одно- строчник показывает, как с помощью регулярных выражений проверять соответствие вводимых пользователем данных семантическим требованиям приложения.
    Поиск удвоенных символов
    в строковых значениях
    Этот однострочник откроет для вас замечательную возможность регулярных выражений: повторное использование частей, для которых уже производил- ся поиск соответствий в том же регулярном выражении. Такое расширение возможностей дает возможность решать новый спектр задач, включая поиск строковых значений с удвоенными символами.
    Общее описание
    На этот раз представьте, что вы как исследователь в сфере вычислительной лингвистики анализируете изменения частоты использования опреде- ленных слов с течением времени. Вы классифицируете слова и изучаете частоту их использования в различных напечатанных книгах. Ваш на- учный руководитель дает задание выяснить наличие тенденции к повы- шению частоты использования удвоенных символов в словах. Например, слово 'hello'
    содержит удвоенную букву 'l'
    , а слово 'spoon'
    содержит удвоенную букву 'o'
    . Слово же 'mama'
    не относится к словам с удвоенной буквой 'a'
    Наивное решение этой задачи — перечислить все возможные варианты удвоения букв 'aa'
    ,
    'bb'
    ,
    'cc'
    ,
    'dd'
    ,
    ,
    'zz'
    и объединить их в одном регулярном выражении. Это решение утомительно для реализации и плохо

    Поиск удвоенных символов в строковых значениях
    203
    поддается обобщению. Что, если ваш научный руководитель передумает и попросит теперь искать удвоенные буквы, которые разделяет один символ
    (например, такие как в 'mama'
    )?
    Никаких проблем: существует простое, аккуратное и эффективное решение для тех, кто умеет обращаться с поименованными группами в регулярных выражениях. Вы уже встречали скобочные группы вида
    (...)
    . Как ясно из названия, поименованная группа (named group) — это просто группа, у которой есть название. Например, описать поименованную группу для шаблона с названием name можно с помощью синтаксиса
    (?P...)
    Описанную поименованную группу можно использовать где угодно в ре- гулярном выражении, прибегнув к синтаксису
    (?P=name)
    . Рассмотрим следующий пример:
    import re pattern = '(?P[\'"]).*(?P=quote)'
    text = 'She said "hi"'
    print(re.search(pattern, text))
    #
    В этом коде мы ищем подстроки, заключенные в одинарные или двойные кавычки. Для этого сначала ищем соответствие для открывающей кавычки с помощью регулярного выражения
    [\'"]
    (одинарную кавычку мы экрани- руем, чтобы Python ошибочно не счел ее символом окончания строкового значения). Далее с помощью той же группы ищем аналогичную закрываю- щую кавычку (одинарную или двойную).
    Прежде чем заняться кодом, отметим, что можно искать соответствие про- извольных пробельных символов с помощью регулярного выражения
    \s
    Можно также искать символы, не входящие во множество
    Y
    , посредством синтаксиса
    [^Y]
    . Вот и все, что нам нужно для решения поставленной за- дачи.
    Код
    Рассмотрим задачу, изложенную в листинге 5.8: найти в заданном тексте все слова с удвоенными символами. Под словом в данном случае понимается произвольная последовательность непробельных символов, отделенных произвольным количеством пробельных символов.

    204
    Глава 5. Регулярные выражения
    Листинг 5.8. Однострочное решение для поиска всех слов с удвоенными символами
    ## Зависимости import re
    ## Данные text = '''
    It was a bright cold day in April, and the clocks were striking thirteen. Winston Smith, his chin nuzzled into his breast in an effort to escape the vile wind, slipped quickly through the glass doors of Victory Mansions,
    though not quickly enough to prevent a swirl of gritty dust from entering along with him.
    -- George Orwell, 1984
    '''
    ## Однострочник duplicates = re.findall('([^\s]*(?P[^\s])(?P=x)[^\s]*)', text)
    ## Результат print(duplicates)
    Какие же слова с удвоенными символами найдет этот код?
    Принцип работы
    Регулярное выражение
    (?P[^\s])
    задает новую группу с названием x
    , которая состоит из одного произвольного непробельного символа. Сразу за поименованной группой x
    следует регулярное выражение
    (?P=x)
    , которому соответствует тот же символ, что и группе x
    . Мы нашли наши удвоенные символы! Однако задача состояла в поиске не просто удвоенных символов, а слов с удвоенными символами. Поэтому мы захватываем еще и произволь- ное число непробельных символов
    [^\s]*
    до и после удвоенного символа.
    Стоит отметить, что это решение не вполне корректно обрабатывает слова, в которых встречается несколько удвоений символов. Оставим усовершен- ствование кода читателю в качестве упражнения.
    Результаты работы листинга 5.8 выглядят следующим образом:
    ## Результаты print(duplicates)
    '''
    [('thirteen.', 'e'), ('nuzzled', 'z'), ('effort', 'f'),
    ('slipped', 'p'), ('glass', 's'), ('doors', 'o'),
    ('gritty', 't'), ('--', '-'), ('Orwell,', 'l')]
    '''

    Поиск повторов слов
    205
    Это регулярное выражение находит в тексте все слова с удвоенными сим- волами. Отметим, что регулярное выражение из листинга 5.8 включает две группы, так что каждый возвращаемый функцией re.findall()
    элемент состоит из кортежа, части которого соответствуют этим группам. Вы уже видели подобное поведение в предыдущих разделах.
    В этом разделе вы добавили в свой набор инструментов регулярных вы- ражений еще один замечательный инструмент: поименованные группы.
    В сочетании с двумя более незначительными возможностями поиска соот- ветствий произвольным пробельным символам с помощью
    \s и описания на- бора символов, которые не должны встречаться на данном месте в шаблоне, с помощью оператора
    [^...]
    вы существенно приблизились к овладению регулярными выражениями Python в совершенстве.
    Поиск повторов слов
    В предыдущем разделе мы рассказали вам о поименованных группах. Задача этого раздела — продемонстрировать продвинутые способы использования данной возможности.
    Общее описание
    Работая в последние несколько лет исследователем, большую часть време- ни я тратил на написание, чтение и редактуру научных статей. Редактируя мои статьи, один из моих коллег часто жаловался, что я постоянно (и очень близко в тексте) использую одни и те же слова. Утилита для проверки на- писанного программным образом мне совсем бы не помешала.
    Код
    Пусть дано строковое значение, состоящее из слов в нижнем регистре, раз- деленных пробелами, без каких-либо специальных символов. Необходимо найти подстроку, в которой первое и последнее слова одинаковы (повторя- ются), причем их разделяет не более десяти слов (листинг 5.9).
    Листинг 5.9. Однострочное решение для поиска повторов слов
    ## Зависимости import re
    ## Данные

    206
    Глава 5. Регулярные выражения text = 'if you use words too often words become used'
    ## Однострочник style_problems = re.search('\s(?P[a-z]+)\s+([a-z]+\s+){0,10}(?P=x)\s',
    ' ' + text + ' ')
    ## Результат print(style_problems)
    Действительно ли этот код находит повторы слов?
    Принцип работы
    Опять же, мы предполагаем, что text состоит только из разделенных про- белами слов в нижнем регистре. И ищем требуемое в text с помощью регу- лярного выражения. Оно может показаться запутанным на первый взгляд, но мы рассмотрим его по частям:
    '\s(?P[a-z]+)\s+([a-z]+\s+){0,10}(?P=x)\s'
    Мы начинаем с отдельного пробельного символа. Это позволяет гарантиро- вать, что первый найденный фрагмент — целое слово (а не суффикс). Далее мы ищем соответствие поименованной группе x
    , состоящее из ненулевого числа символов в нижнем регистре от 'a'
    до 'z'
    , за которым следует нену- левое число пробельных символов .
    Затем мы ищем от 0 до 10 слов, каждое из которых состоит из ненулевого числа символов в нижнем регистре от 'a'
    до 'z'
    , за которым следует нену- левое число пробельных символов .
    И заканчиваем поименованной группой x
    , за которой следует пробельный символ, гарантируя, что последний найденный фрагмент — целое слово
    (а не префикс) .
    Результаты работы этого фрагмента кода выглядят так:
    ## Результаты print(style_problems)
    #
    Мы нашли соответствующую регулярному выражению подстроку, стиль которой можно счесть (или не счесть) плохим.

    Модификация задаваемых регулярными выражениями шаблонов
    207
    В данном однострочнике мы свели задачу поиска повторов слов к простейшей и решили этот более простой вариант. Учтите, что на практике придется учи- тывать и более сложные случаи, например наличие специальных символов, сочетание символов в нижнем и верхнем регистре, чисел и т. д. Либо можно выполнить предварительную обработку и привести текст в желаемый вид: ниж- ний регистр, никаких специальных символов, слова разделяются пробелами.
    УПРАЖНЕНИЕ 5.1
    Напишите сценарий Python, учитывающий возможность наличия специ- альных символов, например символов, используемых для структурной организации предложений (точек, двоеточий, запятых).
    Модификация задаваемых регулярными
    выражениями шаблонов в многострочном
    строковом значении
    В последнем однострочнике вы научитесь модифицировать текст, а не только находить его части, соответствующие регулярному выражению.
    Общее описание
    Для замены всех вхождений конкретного шаблона
    регулярное_выраже-
    ние
    новой строкой символов замена в заданном тексте служит функция re.sub(регулярное_выражение,
    замена,
    текст)
    . С ее помощью можно быстро редактировать большие массивы текста, обходясь без выполнения ручной работы.
    В предыдущих разделах вы научились находить соответствие в тексте ша- блонам регулярных выражений. Но что, если определенный шаблон нужно считать найденным только в том случае, если не встречается какой-то другой шаблон? Задаваемый регулярным выражением
    A(?!X)
    шаблон негативного
    опережающего просмотра (negative lookahead) считается соответствующим регулярному выражению
    A
    , только если далее не найдено регулярное вы- ражение
    X
    . Например, регулярному выражению
    (?!good)
    удовлетворяет строка 'this is not great'
    , но не строка 'this is not good'

    208
    Глава 5. Регулярные выражения
    Код
    Наши данные представляют собой строковое значение, и задача — заменить вхождения
    Alice
    Wonderland на
    Alice
    Doe
    , не заменяя при этом вхождений 'Alice
    Wonderland'
    (заключенных в одинарные кавычки) (листинг 5.10).
    Листинг 5.10. Однострочное решение для замены комбинаций символов в тексте
    ## Зависимости import re
    ## Данные text = '''
    Alice Wonderland married John Doe.
    The new name of former 'Alice Wonderland' is Alice Doe.
    Alice Wonderland replaces her old name 'Wonderland' with her new name 'Doe'.
    Alice's sister Jane Wonderland still keeps her old name.
    '''
    ## Однострочник updated_text = re.sub("Alice Wonderland(?!')", 'Alice Doe', text)
    ## Результат print(updated_text)
    Этот код выводит модифицированный текст. Какой?
    Принцип работы
    Мы заменяем все вхождения
    Alice
    Wonderland на
    Alice
    Doe
    , кроме тех, кото- рые заканчиваются одинарной кавычкой '
    . Для этого мы воспользовались не- гативным опережающим просмотром. Обратите внимание, что мы проверяем только наличие закрывающей кавычки. Например, нашему регулярному выражению удовлетворяет строковое значение с открывающей кавычкой, но
    без закрывающей, так что мы просто заменим его. В общем случае это может быть нежелательно, но в нашем конкретном примере строкового значения приводит к желаемому поведению:
    ## Результат print(updated_text)
    '''
    Alice Doe married John Doe.
    The new name of former 'Alice Wonderland' is Alice Doe.
    Alice Doe replaces her old name 'Wonderland' with her new name 'Doe'.
    Alice's sister Jane Wonderland still keeps her old name.
    '''

    Итоги главы
    209
    Как видите, исходное имя 'Alice
    Wonderland'
    не меняется, когда заключено в одинарные кавычки, — что нам и нужно было.
    Итоги главы
    В этой главе мы охватили очень многое. Вы узнали о том, как искать соот- ветствие шаблону в заданной строке с помощью регулярных выражений.
    В частности, узнали о функциях re.compile()
    , re.match()
    , re.search()
    , re.findall()
    и re.sub()
    . Вместе взятые, они охватывают значительную долю сценариев использования регулярных выражений. По мере применения регу- лярных выражений на практике вы познакомитесь и с другими функциями.
    Кроме того, вы изучили различные простые регулярные выражения, ком- бинации которых позволяют создавать более сложные. Вдобавок вы узнали о пробельных символах, экранировании символов, «жадных»/«нежадных» операторах, наборах символов (и негативных наборах символов), группиров- ке и поименованных группах, а также о негативном опережающем просмотре.
    И наконец, вы узнали, что зачастую лучше решить упрощенный вариант ис- ходной задачи, чем пытаться с самого начала получить обобщенное решение.
    Вам осталось только начать применять новоприобретенные знания о ре- гулярных выражениях на практике. Чтобы привыкнуть к регулярным вы- ражениям, лучше всего пробовать использовать их в своей любимой про- грамме для редактирования текста. Большинство продвинутых программ для редактирования текста и кода (включая Notepad++) включает широкую функциональность по работе с регулярными выражениями. Кроме того, за- думайтесь о применении регулярных выражений при работе с текстовыми данными (например, при написании электронных писем, сообщений в бло- гах, книг и кода). Регулярные выражения очень упрощают жизнь и экономят многие часы утомительной работы.
    В следующей главе мы углубимся в важнейшую составляющую програм- мирования: алгоритмы.

    6
    Алгоритмы
    Алгоритмы известны уже очень давно. Алгоритм — это просто набор инструкций наподобие кулинарного рецепта. Однако важность роли алгоритмов в обществе стремительно растет: алгоритмы и основанный на них процесс принятия решений проникают во все сферы по мере того, как компьютеры становятся все более важной частью нашей жизни.
    В исследовании 2018 года подчеркивается, что «данные в виде наблюдений над нашим миром насквозь пропитывают современное общество... Эта ин- формация может, в свою очередь, использоваться для принятия взвешен- ных — а в некоторых случаях даже полностью автоматизированных — реше- ний... Вполне вероятно, что подобные алгоритмы в будущем будут активно участвовать в процессах принятия решений людьми, что необходимо для общественного признания, а значит, и широкомасштабного применения».
    ПРИМЕЧАНИЕ
    Больше информации об этом исследовании вы можете найти в статье
    The Growing Ubiquity of Algorithms in Society: Implications, Impacts, and
    Innovations авторов S. C. Olhede и P. J. Wolfe: https://royalsocietypublishing.
    org/doi/full/10.1098/rsta.2017.0364#d2696064e1.

    Алгоритмы
    211
    По мере развития в обществе тенденций к автоматизации, искусственному интеллекту и повсеместному применению компьютеров социальная про- пасть между теми, кто понимает алгоритмы, и теми, кто их не понимает, стремительно ширится. Например, в сфере логистики наблюдается мас- штабная тенденция к автоматизации, в том числе появляются беспилотные автомобили и грузовики, и профессиональные водители вынуждены принять тот факт, что алгоритмы постепенно отбирают у них работу.
    Постоянная смена спектра востребованных навыков и специальностей в XXI столетии требует от молодежи понимания, умения настраивать и ме- нять простые алгоритмы. И когда неизменно только изменение, основные идеи алгоритмов и теории алгоритмов формируют фундамент, на котором основываются многие грядущие изменения. Проще говоря, понимание ал- горитмов гарантирует ваше процветание в ближайшие десятилетия.
    Эта глава призвана расширить ваше понимание алгоритмов, делая упор скорее на интуитивном и всестороннем понимании основных идей и реа- лизаций на практике, чем на теории. И хотя теория алгоритмов ничуть не менее важна, чем реализация их на практике и понимание на понятийном уровне, многие замечательные книги посвящены в основном теории. Про- читав данную главу, вы будете интуитивно понимать некоторые наиболее популярные в computer science алгоритмы и еще больше разовьете навыки практической реализации на языке Python. Это обеспечит вам надежный фундамент для будущих научно-технических прорывов.
    ПРИМЕЧАНИЕ
    Книга Томаса Кормена (Thomas Cormen) и др. Introduction to Algorithms
    (MIT Press, 2009)
    1
    замечательный источник дополнительной инфор- мации по теории алгоритмов.
    Начнем с маленького алгоритма, предназначенного для решения про- стой задачи, актуальной для программистов, желающих найти хорошую работу.
    1
    Кормен Т. Х., Лейзерсон Ч. И., Ривест Р. Л., Штайн К. Алгоритмы: построение и анализ.
    3-е изд. — М.: Вильямс, 2013.

    212
    Глава 6. Алгоритмы
    Поиск анаграмм с помощью лямбда-функций
    и сортировки
    Анаграммы — часто встречающийся при собеседованиях программистов вопрос на проверку кругозора в области компьютерных наук и умения раз- рабатывать собственные простые алгоритмы. В этом разделе мы расскажем о простом алгоритме для поиска анаграмм на языке Python.
    Общее описание
    Два слова являются анаграммами, если состоят из одинаковых символов и каждый символ первого из них встречается во втором ровно один раз.
    Ниже в списке и на рис. 6.1 даны несколько примеров:
    listen
    silent;
    funeral
    real fun;
    elvis
    lives.
    1   ...   13   14   15   16   17   18   19   20   21


    написать администратору сайта