Треки
/
Go
Go
/
Салабус
/
Регулярні вирази
Ре

Регулярні вирази у Go

1 вправа

Про концепцію Регулярні вирази

Пакет regexp надає підтримку регулярних виразів у Go.

Синтаксис

Прийняті регулярні вирази мають синтаксис, той самий загальний синтаксис, який використовують Perl, Python та інші мови.

І шаблони пошуку, і вхідні тексти інтерпретуються як UTF-8.

Коли ми використовуємо зворотні лапки (`) to make strings, backslashes (\) don't have any special meaning and don't mark the beginning of special characters like tabs \t or newlines \n:

"\t\n" // regular string literal with 2 characters: a tab and a newline
`\t\n`// raw string literal with 4 characters: two backslashes, a 't', and an 'n'

Через це для створення регулярних виразів бажано використовувати зворотні лапки, адже тоді не потрібно екранувати зворотні слеші:

"\\" // string with a single backslash
`\\` // string with 2 backslashes

Компіляція шаблонів - тип RegExp

Щоб скористатися регулярним виразом, спершу треба скомпілювати рядковий шаблон. Компіляція тут означає, що ми беремо рядковий шаблон регулярного виразу й перетворюємо його на внутрішнє представлення, з яким зручніше працювати. Кожен шаблон достатньо скомпілювати лише раз, після чого скомпільовану версію регулярного виразу можна використовувати багато разів. Тип regexp.Regexp представляє скомпільований регулярний вираз. Ми можемо скомпілювати рядковий шаблон у regexp.Regexp за допомогою функції regexp.Compile. Якщо компіляція не вдалася, ця функція повертає nil і помилку:

re, err := regexp.Compile(`(a|b)+`)
fmt.Println(re, err) // => (a|b)+ <nil>
re, err = regexp.Compile(`a|b)+`)
fmt.Println(re, err) // => <nil> error parsing regexp: unexpected ): `a|b)+`

Функція MustCompile - зручна альтернатива Compile:

re = regexp.MustCompile(`[a-z]+\d*`)

Користуючись цією функцією, не потрібно обробляти помилку.

Caution

MustCompile варто використовувати лише тоді, коли ми точно знаємо, що шаблон компілюється, інакше програма запанікує.

Методи регулярних виразів

Існує 16 методів Regexp, які знаходять збіги з регулярним виразом і визначають текст, що збігся. Їхні назви відповідають цьому регулярному виразу:

Find(All)?(String)?(Submatch)?(Index)?
  • Якщо присутній All, метод знаходить послідовні збіги всього виразу, що не перекриваються.
  • Якщо присутній String, аргумент є рядком тексту; інакше це зріз байтів; повернені значення відповідно змінюються.
  • Якщо присутній Submatch, повернене значення є зрізом, який визначає послідовні підзбіги виразу.
  • Якщо присутній Index, збіги й підзбіги визначаються парами байтових індексів у вхідному рядку тексту.

Є також методи для:

  • заміни збігів регулярних виразів рядками заміни та
  • розбиття рядків тексту, розділених регулярними виразами.

Загалом пакет regexp визначає понад 40 функцій і методів. Нижче ми продемонструємо використання кількох методів. Докладніше про ці та інші функції дивіться в документації API.

Приклади MatchString

Метод MatchString повідомляє, чи містить рядок тексту хоч один збіг з регулярним виразом.

re = regexp.MustCompile(`[a-z]+\d*`)
b = re.MatchString("[a12]")       // => true
b = re.MatchString("12abc34(ef)") // => true
b = re.MatchString(" abc!")       // => true
b = re.MatchString("123 456")     // => false

Приклади FindString

Метод FindString повертає рядок тексту з текстом найлівішого збігу регулярного виразу.

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.FindString("[a12]")       // => "a12"
s = re.FindString("12abc34(ef)") // => "abc34"
s = re.FindString(" abc!")       // => "abc"
s = re.FindString("123 456")     // => ""

Приклади FindStringSubmatch

Метод FindStringSubmatch повертає зріз рядків тексту, що містить текст найлівішого збігу регулярного виразу та збіги його підвиразів, якщо вони є. Це дає змогу визначити рядки тексту, що відповідають групам захоплення. Повернене значення nil означає відсутність збігу.

re = regexp.MustCompile(`[a-z]+(\d*)`)
sl = re.FindStringSubmatch("[a12]")       // => []string{"a12","12"}
sl = re.FindStringSubmatch("12abc34(ef)") // => []string{"abc34","34"}
sl = re.FindStringSubmatch(" abc!")       // => []string{"abc",""}
sl = re.FindStringSubmatch("123 456")     // => <nil>

Приклади ReplaceAllString

Метод re.ReplaceAllString(src,repl) повертає копію src, замінюючи збіги регулярного виразу re рядком заміни repl.

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.ReplaceAllString("[a12]", "X")       // => "[X]"
s = re.ReplaceAllString("12abc34(ef)", "X") // => "12X(X)"
s = re.ReplaceAllString(" abc!", "X")       // => " X!"
s = re.ReplaceAllString("123 456", "X")     // => "123 456"

Приклади Split

Метод re.Split(s,n) розбиває текст s на підрядки, розділені виразом, і повертає зріз підрядків між цими збігами виразу. Лічильник n визначає максимальну кількість підрядків, які потрібно повернути. Якщо n<0, метод повертає всі підрядки.

re = regexp.MustCompile(`[a-z]+\d*`)
sl = re.Split("[a12]", -1)      // => []string{"[","]"}
sl = re.Split("12abc34(ef)", 2) // => []string{"12","(ef)"}
sl = re.Split(" abc!", -1)      // => []string{" ","!"}
sl = re.Split("123 456", -1)    // => []string{"123 456"}

Продуктивність

Реалізація регулярних виразів у цьому пакеті гарантовано працює за час, лінійний від розміру вхідних даних.

Застереження

Пакет regexp реалізує регулярні вирази RE2 (крім \C). Синтаксис здебільшого сумісний із PCRE («Perl Compatible Regular Expression»), але є деякі відмінності. Докладніше дивіться в розділі «Застереження» у цій статті.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Регулярні вирази

Практика заблокована

Розблокуйте ще 2 вправи, щоб практикувати концепцію Регулярні вирази