Регулярное выражение - это последовательность символов, которые определяют шаблон поиска.
Регулярное выражение a.b соответствует любой строке, которая начинается с a, заканчивается на b и содержит один символ между ними (точка соответствует любому символу).
Чтобы проверить, существует ли подстрока, соответствующая a.b, используйте функцию regexp.MatchString.
matched, err := regexp.MatchString(`a.b`, "aaxbb")
fmt.Println(matched) // true
fmt.Println(err) // nil (regexp валидно)
Чтобы проверить, соответствует ли полная строка a.b, закрепите начало и конец регулярного выражения:
- символ каретки ^ соответствует началу текста или строки,
- символ доллара $ соответствует концу текста.
matched, _ := regexp.MatchString(`^a.b$`, "aaxbb")
fmt.Println(matched) // false
Точно так же мы можем проверить, начинается ли строка с или заканчивается шаблоном, используя только начальную или конечную привязку.
Compile
Для более сложных запросов вы должны скомпилировать регулярное выражение для создания объекта Regexp. Есть два варианта:
re1, err := regexp.Compile(`regexp`) // error если regexp невалидно
re2 := regexp.MustCompile(`regexp`) // panic если regexp невалидно
Необработанные строки (Raw strings)
При написании регулярных выражений удобно использовать `raw strings`, поскольку как обычные строковые литералы, так и регулярные выражения используют обратные слэши для специальных символов.
Необработанная строка, разделенная обратными кавычками, интерпретируется буквально, а обратная косая черта (обратный слэш) не имеет особого значения.
Регулярные выражения
Выбор и группировка
Regexp | Значение |
---|---|
xy | х с последующим у |
x|y | х или у, предпочитает х |
xy|z | такой же, как (xy)|z |
xy* | такой же как х(у*) |
Повторение (жадное (greedy) и не жадное (non-greedy))
Regexp | Значение |
---|---|
x* | ноль или более х, предпочитает больше |
x*? | ноль или более х, предпочитает меньше (не жадное) |
x+ | один или несколько х, предпочитает больше |
x+? | один или несколько х, предпочитает меньше (не жадное) |
x? | ноль или один х, предпочитает один |
x?? | ноль или один х, предпочитает ноль |
x{n} | x точно n раз |
Классы символов
Regexp | Значение |
---|---|
. | (точка) любой символ |
[ab] | символ a или b |
[^ab] | любой символ исключая a или b |
[a-z] | любой символ от a до z |
[a-z0-9] | любой символ от a до z или от 0 до 9 |
\d | цифра: [0-9] |
\D | не цифра: [^0-9] |
\s | пробельный символ: [\t\n\f\r ] |
\S | не пробельный символ: [^\t\n\f\r ] |
\w | символ слова: [0-9A-Za-z_] |
\W | несловесный символ: [^0-9A-Za-z_] |
\p{Greek} | класс символов Unicode (RE2: имена классов символов Unicode) |
\pN | однобуквенное имя |
\P{Greek} | исключая класс символов Unicode (RE2: имена классов символов Unicode) |
\PN | исключая класс символов Unicode - однобуквенное имя |
Специальные символы
Чтобы сопоставить специальный символ \^$.|?*+-[]{}() буквально, экранируйте (escape) его обратной косой чертой. Например, \{ соответствует открывающей фигурной скобке.
Другие escape-последовательности:
Символ | Значение |
---|---|
\t | символ горизонтальной табуляции (horizontal tab) = \011 |
\n | символ новой строки (newline) = \012 |
\f | form feed = \014 |
\r | символ возврата каретки = \015 |
\v | символ вертикальной табуляции (vertical tab) = \013 |
\123 | восьмеричный код символа (до трех цифр) |
\x7F | шестнадцатеричный код (ровно две цифры) |
Якори границ текста
Символ | Значение |
---|---|
\A | в начале текста |
^ | в начале текста или строки |
$ \z |
в конце текста |
\b | на границе ASCII слова |
\B | не на границе ASCII слова |
Регистрозависимые и многострочные совпадения
Чтобы изменить поведение сопоставления по умолчанию, вы можете добавить набор флагов в начало регулярного выражения.
Например, префикс "(?is)" делает сопоставление без учета регистра и позволяет . (точке) совпадать \n. (Соответствие по умолчанию чувствительно к регистру и . (точка) не соответствует \n.)
Флаг | Значение |
---|---|
i | не чувствительны к регистру |
m | позволяет ^ и $ соотвествовать началу/концу строки в дополнение к началу/концу текста (многострочный режим) |
s | позволяет . (точка) соотвествовать \n (однострочный режим) |
Примеры кода
Первое совпадение
Используйте метод FindString, чтобы найти текст первого совпадения. Если совпадений нет, возвращаемое значение - пустая строка.
re := regexp.MustCompile(`foo.?`)
fmt.Printf("%q\n", re.FindString("seafood fool")) // "food"
fmt.Printf("%q\n", re.FindString("meat")) // ""
Место расположения
Используйте метод FindStringIndex, чтобы найти loc, местоположение первого совпадения, в строке s. Совпадение в s[loc[0]:loc[1]]. Возвращаемое значение nil указывает на отсутствие совпадения.
re := regexp.MustCompile(`ab?`)
fmt.Println(re.FindStringIndex("tablett")) // [1 3]
fmt.Println(re.FindStringIndex("foo") == nil) // true
Все совпадения
Используйте метод FindAllString, чтобы найти текст всех совпадений. Возвращаемое значение nil указывает на отсутствие совпадения.
Метод принимает целочисленный аргумент n; если n >= 0, функция возвращает не более n совпадений.
re := regexp.MustCompile(`a.`)
fmt.Printf("%q\n", re.FindAllString("paranormal", -1)) // ["ar" "an" "al"]
fmt.Printf("%q\n", re.FindAllString("paranormal", 2)) // ["ar" "an"]
fmt.Printf("%q\n", re.FindAllString("graal", -1)) // ["aa"]
fmt.Printf("%q\n", re.FindAllString("none", -1)) // [] (nil slice)
Замещение (Replace)
Используйте метод ReplaceAllString для замены текста всех совпадений. Он возвращает копию, заменяя все совпадения регулярного выражения строкой замены.
re := regexp.MustCompile(`ab*`)
fmt.Printf("%q\n", re.ReplaceAllString("-a-abb-", "T")) // "-T-T-"
Метод Split
Используйте метод Split, чтобы разрезать строку на подстроки, разделенные регулярным выражением. Он возвращает часть подстрок между этими совпадениями выражений. Возвращаемое значение nil указывает на отсутствие совпадения.
Метод принимает целочисленный аргумент n; если n >= 0, функция возвращает не более n совпадений.
a := regexp.MustCompile(`a`)
fmt.Printf("%q\n", a.Split("banana", -1)) // ["b" "n" "n" ""]
fmt.Printf("%q\n", a.Split("banana", 0)) // [] (nil slice)
fmt.Printf("%q\n", a.Split("banana", 1)) // ["banana"]
fmt.Printf("%q\n", a.Split("banana", 2)) // ["b" "nana"]
zp := regexp.MustCompile(`z+`)
fmt.Printf("%q\n", zp.Split("pizza", -1)) // ["pi" "a"]
fmt.Printf("%q\n", zp.Split("pizza", 0)) // [] (nil slice)
fmt.Printf("%q\n", zp.Split("pizza", 1)) // ["pizza"]
fmt.Printf("%q\n", zp.Split("pizza", 2)) // ["pi" "a"]
Больше функций
Есть 16 функций, следующих шаблону именования
Find(All)?(String)?(Submatch)?(Index)?
Например: Find, FindAllString, FindStringIndex, ...
- Если присутствует All, функция сопоставляет последовательные непересекающиеся совпадения.
- String указывает, что аргумент является строкой; в противном случае это срез байтов.
- Если Submatch присутствует, возвращаемое значение представляет собой срез последовательных подсовпадений. Подсовпадения - это совпадения заключенных в скобки подвыражений в регулярном выражении.
- Если Index присутствует, совпадения и субсовпадения идентифицируются парами байтовых индексов.
Реализация
- Пакет regexp реализует регулярные выражения с синтаксисом RE2.
- Он поддерживает строки в кодировке UTF-8 и классы символов Unicode.
- Реализация очень эффективна: время выполнения линейно по размеру ввода.
- Обратные ссылки не поддерживаются, поскольку они не могут быть эффективно реализованы.
Читайте также:
- Массивы, срезы и строки: механика работы append в Golang
- Срезы в Golang: внутреннее устройство и использование
- Эффективный Go: срезы (slices)
Комментариев нет:
Отправить комментарий