Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Go
Code

Регулярные выражения с Go: часть 1

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Regular Expressions With Go.
Regular Expressions With Go: Part 2

Russian (Pусский) translation by Masha Kolesnikova (you can also view the original English article)

Обзор

Регулярные выражения (AKA regex) - это формальный язык, который определяет последовательность символов с некоторым шаблоном. В реальном мире их можно использовать для решения множества проблем с полуструктурированным текстом. Вы можете извлечь важные фрагменты из текста с большим количеством декораторов или несвязанного содержимого. Go имеет в своей стандартной библиотеке надежный пакет регулярных выражений, который позволяет вырезать текст с помощью регулярных выражений.

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

Понимание регулярных выражений

Давайте начнем с быстрого примера. У вас есть текст, и вы хотите проверить, содержит ли он адрес электронной почты. Адрес электронной почты строго указан в RFC 822. Короче говоря, он имеет локальную часть, за которой следует символ @, за которым следует домен. Почтовый адрес будет отделен от остального текста пробелом.

Чтобы выяснить, содержит ли он адрес электронной почты, подойдет следующее регулярное выражение: ^\w+@\w+\.\w+$. Обратите внимание, что это регулярное выражение пропустит некоторые недействительные адреса электронной почты. Но этого достаточно, чтобы продемонстрировать концепцию. Давайте попробуем это на паре потенциальных адресов электронной почты, прежде чем объяснять, как это работает:

Наше регулярное выражение работает на этом маленьком образце. Первые два адреса были отклонены, поскольку в домене не было точки или не было символов после точки. Третье письмо было отформатировано правильно. У последнего кандидата было два символа @.

Давайте разберем это регулярное выражение: ^\w+@\w+\.\w+$

Символ Смысл
^ Начало целевого текста
\w Любые символы слова [0-9A-Za-z_]
+ Хотя бы один из предыдущих символов
@ Буквально символ @
\. Буквенный точечный символ. Нужно начинать с \
$ Конец целевого текста

В целом, это регулярное выражение будет соответствовать фрагментам текста, которые начинаются с одного или нескольких символов слова, после которых следует символ "@", затем снова один или несколько символов слова, затем точка и затем снова один или несколько символов слова.

Работа со специальными символами

Следующие символы имеют специальные значения в регулярных выражениях: .+*?()|[]{}^$\. Мы уже видели многих из них в примере электронной почты. Если мы хотим сопоставить их буквально, нам нужно экранировать их с обратной косой чертой. Давайте представим небольшую вспомогательную функцию под названием match(), которая сэкономит нам много текста. Она берет шаблон и некоторый текст, использует метод regexp.Match() для сопоставления шаблона с текстом (после преобразования текста в байтовый массив) и печатает результаты:

Вот пример соответствия обычного символа, такого как z, и соответствия специального символа, такого как ?:

Шаблон регулярного выражения \? содержит обратную косую черту, которая должна быть экранирована другой обратной косой чертой, когда она представлена в виде обычной строки Go. Причина в том, что обратная косая черта также используется для экранирования специальных символов в строках Go, таких как символ новой строки (\n). Если вы хотите сопоставить сам символ обратной косой черты, вам понадобится четыре слеша!

Решение состоит в том, чтобы использовать строки Go raw с обратным кавычком (`) вместо двойных кавычек. Конечно, если вы хотите сопоставить символ новой строки, вы должны вернуться к обычным строкам и иметь дело с множественными символами обратной косой черты.

Заполнители и повторы

В большинстве случаев вы не пытаетесь буквально сопоставить последовательность определенных символов, таких как «abc», но последовательность неизвестной длины, возможно, с некоторыми известными символами, вставленными где-то. Регулярные выражения поддерживают этот вариант использования с точкой . специальный символ, который обозначает любой символ. Специальный символ * повторяет предыдущий символ (или группу) ноль или более раз. Если вы объединяете их, как в .*, то вы сопоставляете что угодно, потому что это просто означает ноль или более символов. Знак + очень похож на *, но соответствует одному или нескольким предыдущим символам или группам. Итак .+ будет соответствовать любому непустому тексту.

Использование границ

Есть три типа границ: начало текста, обозначенного ^, конец текста, обозначенного $, и граница слова, обозначенная \b. Например, рассмотрим текст из классического фильма «Принцесса-невеста»: «Меня зовут Иниго Монтойя. Ты убил моего отца. Приготовьтесь умереть." Если вы соответствуете просто "папа", вы получите совпадение, но если вы ищете "папа" в конце текста, вам нужно добавить символ $, и тогда совпадения не будет. С другой стороны, соответствие "Hello" в начале работает хорошо.

Границы слова смотрят на каждое слово. Вы можете начать и/или закончить шаблон с помощью \b. Обратите внимание, что знаки препинания, такие как запятые, считаются границей, а не частью слова. Вот несколько примеров:

Используем классы

Часто полезно рассматривать все группы символов вместе как все цифры, пробельные символы или все буквенно-цифровые символы. Golang поддерживает классы POSIX, которые:

Класс Значение
[:alnum:]
буквенно-цифровой (≡ [0-9A-Za-z])
[:alpha:]
буквенный (≡ [A-Za-z])
[:ascii:]
ASCII (≡ [\ x00- \ x7F])
[:blank:]
пусто (≡ [\ t])
[:cntrl:]
управление (≡ [\ x00- \ x1F \ x7F])
[:digit:]
цифры (≡ [0-9])
[:graph:]
графический (≡ [! - ~] == [A-Za-z0-9! "# $% & '() * +, \ -. / :; <=>? @ [\\\] ^ _` { |} ~])
[:lower:]
строчные буквы (≡ [a-z])
[:print:]
для печати (≡ [- ~] == [[: graph:]])
[:punct:]
пунктуация (! [! - /: - @ [- `{- ~])
[:space:]
пробел (≡ [\ t \ n \ v \ f \ r])
[:upper:]
верхний регистр (A [A-Z])
[:word:]
символы слова (≡ [0-9A-Za-z_])
[:xdigit:]
шестнадцатеричная цифра (≡ [0-9A-Fa-f])

В следующем примере я буду использовать класс [:digit:] для поиска чисел в тексте. Кроме того, я покажу здесь, как искать точное количество символов, добавляя запрошенное число в фигурных скобках.

Вы также можете определять свои собственные классы, помещая символы в квадратные скобки. Например, если вы хотите проверить, является ли какой-либо текст допустимой последовательностью ДНК, содержащей только символы ACGT, используйте регулярное выражение ^[ACGT]*$:

Использование альтернатив

В некоторых случаях существует несколько жизнеспособных альтернатив. Соответствующие URL-адреса HTTP могут характеризоваться схемой протокола, которая может быть либо http://, либо https://. Символ трубы | позволяет выбирать между альтернативами. Вот регулярное выражение, которое будет сортировать их: (http)|(https)://\w+\.\w{2,}. Он переводится в строку, которая начинается с http:// или https://, за которым следует хотя бы один символ слова, за которым следует точка, за которой следуют как минимум два символа слова.

Заключение

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

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

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.