Пакет 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*`)
Користуючись цією функцією, не потрібно обробляти помилку.
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»), але є деякі відмінності.
Докладніше дивіться в розділі «Застереження» у цій статті.