Используйте регулярное выражение

Go

Методические рекомендации

  • По умолчанию используется кратчайшее совпадение, которое возвращается, если строка удовлетворяет условию.
  • Если совпадений нет, возвращается какnil.
  • Чтобы сделать самый длинный матч, позвонитеLongest()функция.
  • Функции регулярных выражений: match (math), find (найти) и replace (заменить).
  • Есть функция выбора длины, переданная в<0Число означает соответствие всем.

вызов с регулярным выражением

Match, MatchReader и MatchString

// 判断b中是够包含pattern能够组成的任意字符串
func Match(pattern string, b []byte) (matched bool, err error) 

// 判断reader r中返回的字符串是否包含pattern能够组成的任意字符串
func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)

// 判断字符串s中是否包含pattern能够组成的任意字符串
func MatchString(pattern string, s string) (matched bool, err error)

Компиляция и MushCompile

  • func Compile(expr string) (*Regexp, error)
  • func MustCompile(str string) *Regexp

Compile:возвращениеRegexpобъект, который удобен для вызова функций указателя.

MustCompile: То же, что и при компиляции, если выражение синтаксического анализа завершится ошибкой, произойдет паника.

При сопоставлении текста регулярное выражение начнет сопоставление как можно раньше и выберет первый совпадающий результат, отслеживаемый в процессе сопоставления. Этот режим называетсяleftmost-first, и в общем использованииMustCompileВот и все.

Используйте объект regexp.Regexp для вызова

Найти и найти все

  • func (re *Regexp) Find(b []byte) []byte
  • func (re *Regexp) FindAll(b []byte, n int) [][]byte

Find возвращает срез []byte, который содержит самый левый совпадающий результат регулярного выражения re в b. Если совпадений нет, возвращается ноль, максимум одно совпадение.

re := regexp.MustCompile(`foo.?`)
fmt.Printf("%q\n", re.Find([]byte(`seafood fool`)))
re := regexp.MustCompile(`foo.?`)
fmt.Printf("%q\n", re.FindAll([]byte(`seafood fool`), -1))

FindAllфункция иFindТо же самое, только вернуть все данные, соответствующие условиям.

FindString и FindAllString

  • func (re *Regexp) FindString(s string) string
  • func (re *Regexp) FindAllString(s string, n int) []string

иFindиFindAllТо же самое, только для строковых строковых операций.

FindIndex и FindAllIndex

  • func (re *Regexp) FindIndex(b []byte) (loc []int)

  • func (re *Regexp) FindAllIndex(b []byte, n int) [][]int

FindIndex, возвращениеbНачальная позиция, которая удовлетворяет совпадающей части строки, также является принципом «самый левый-первый», и loc включает начальную и конечную позиции. Если не найдено, вернитесь напрямуюnil.

FindAllIndex, функция иFindIndexБудьте последовательны, просто сопоставьте несколько,nопределяет совпадающую позицию.

FindStringIndex и FindAllStringIndex

  • func (re *Regexp) FindStringIndex(s string) (loc []int)
  • func (re *Regexp) FindAllStringIndex(s string, n int) [][]int

иFindIndexиFindAllIndexИспользование аналогично, но для строки string.

FindStringSubmatch и FindAllStringSubmatch

  • func (re *Regexp) FindStringSubmatch(s string) []string

FindStringSubmatch: Используйте принцип левого сопоставления, сопоставьте не более одного, если нет, вернитеnil. для возвращенных[]string, соответственно указывают совпадающую строку и подстроку.

re := regexp.MustCompile(`a(x*)b(y|z)c`)
fmt.Printf("%q\n", re.FindStringSubmatch("-axxxbyc-"))
fmt.Printf("%q\n", re.FindStringSubmatch("-abzc-"))

Выходной результат:

["axxxbyc" "xxx" "y"]
["abzc" "" "z"]
  • func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string

иFindStringSubmatchИспользуйте похожие, но вы можете выбрать подходящую длину,-1означает совпадение до конца.

re := regexp.MustCompile(`a(x*)b`)
fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-", -1))
fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-", -1))
fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-axb-", -1))
fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-ab-", -1))

Выходной результат:

[["ab" ""]]
[["axxb" "xx"]]
[["ab" ""] ["axb" "x"]]
[["axxb" "xx"] ["ab" ""]]

FindSubmatchIndex и FindAllSubmatchIndex

  • func (re *Regexp) FindSubmatchIndex(b []byte) []int
  • func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int Вычислить позицию подстроки в исходной строке, которая уже существует(x*)Дождитесь обработки возвращаемого результата, если он не возвращенnil.

Кроме того,indexвозвращается какСлева закрыто справа открыторежим, например2,2Указывает значение пустой строки. И не будет совпадающих совпадений, таких как "-axxb-ab-" для совпаденияa(x*)b, первого не будетaи последнееbкомбинированный случай, если используетсяLongestбудет соответствовать самому длинному.

re := regexp.MustCompile(`a(x*)b`)
// Indices:
//    01234567   012345678
//    -ab-axb-   -axxb-ab-
fmt.Println(re.FindAllStringSubmatchIndex("-ab-", -1))
fmt.Println(re.FindAllStringSubmatchIndex("-axxb-", -1))
fmt.Println(re.FindAllStringSubmatchIndex("-ab-axb-", -1))
fmt.Println(re.FindAllStringSubmatchIndex("-axxb-ab-", -1))
fmt.Println(re.FindAllStringSubmatchIndex("-foo-", -1))

Выходной результат:

[[1 3 2 2]] // 2 2 表示为空
[[1 5 2 4]]
[[1 3 2 2] [4 7 5 6]]
[[1 5 2 4] [6 8 7 7]]
[]

FindStringSubmatchIndex и FindAllStringSubmatchIndex

  • func (re *Regexp) FindStringSubmatchIndex(s string) []int
  • func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int

иFindSubmatchIndex,FindAllSubmatchIndexбыть последовательным.

Longest

  • func (re *Regexp) Самый длинный() Получите самое длинное совпадающее содержимое, удовлетворяющее условию.
re := regexp.MustCompile(`a(|b)`)
fmt.Println(re.FindString("ab"))
re.Longest()
fmt.Println(re.FindString("ab"))

Выходной результат:

a
ab

Следующий случай не будет самым длинным матчем.

re := regexp.MustCompile(`a(x*)b`)
re.Longest()
fmt.Println(re.FindString("-axxb-ab-")) // axxb,不会存在第一个a和最后一个b组合的过程。

Match, MatchString и MatchReader

  • func (re *Regexp) Match(b []byte) bool
  • func (re *Regexp) MatchString(s string) bool
  • func (re *Regexp) MatchReader(r io.RuneReader) bool

судитьb,sиrУдовлетворяют ли возвращаемые данные регулярному выражению, returntrueилиfalse.

NumSubexp

  • func (re *Regexp) NumSubexp() int

Возвращает количество групп.

re0 := regexp.MustCompile(`a.`)
fmt.Printf("%d\n", re0.NumSubexp())

re := regexp.MustCompile(`(.*)((a)b)(.*)a`)
fmt.Println(re.NumSubexp())

Выходной результат:

0
4

Заменить все и заменить все строки

  • func (re *Regexp) ReplaceAll(src, repl []byte) []byte
  • func (re *Regexp) ReplaceAllString(src, repl string) string

ReplaceAllStringиReplaceAllИспользуйте так же.

re := regexp.MustCompile(`a(x*)b`)
fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("T")))  
fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("$1"))) // $1表示匹配的第一个子串,这是ab的中间无字符串,所以$1为空,然后使用空去替换满足正则表达式的部分。
fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("$1W"))) // "$1W"等价与"$(1W)",值为空,将满足条件的部分完全替换为空。
fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("${1}W"))) // ${1}匹配(x*),保留。输出-W-xxW-

Выходной результат:

-T-T-
--xx-
---
-W-xxW-
s := "Hello World, 123 Go!"
//定义一个正则表达式reg,匹配Hello或者Go
reg := regexp.MustCompile(`(Hell|G)o`)

s2 := "2019-12-01,test"
//定义一个正则表达式reg2,匹配 YYYY-MM-DD 的日期格式
reg2 := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)

//最简单的情况,用“T替换”"-ab-axxb-"中符合正则"a(x*)b"的部分
reg3 := regexp.MustCompile("a(x*)b")
fmt.Println(re.ReplaceAllString("-ab-axxb-", "T")) // -T-T-

//${1}匹配"Hello World, 123 Go!"中符合正则`(Hell|G)`的部分并保留,去掉"Hello"与"Go"中的'o'并用"ddd"追加
rep1 := "${1}ddd"
fmt.Printf("%q\n", reg.ReplaceAllString(s, rep1)) // Hellddd World, 123 Gddd!

//首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{4})'的'2019'保留,去掉剩余部分
rep2 := "${1}"
fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep2)) // 2019,test

//首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'12'保留,去掉剩余部分
 rep3 := "${2}"
fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep3)) // 12,test

//首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'01'保留,去掉剩余部分,并追加"13:30:12"
rep4 := "${3}:13:30:12"
fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep4)) // 01:13:30:12,test
}

ReplaceAllFunc и ReplaceAllStringFunc

  • func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte
  • func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string

будут соответствовать тем, которые соответствуют условиям[]byteпередается как параметр функции.

re := regexp.MustCompile(`[^aeiou]`)
fmt.Println(re.ReplaceAllStringFunc("seafood fool", strings.ToUpper))

Оба используются аналогично.

ReplaceAllLiteral и ReplaceAllLiteralString

  • func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte
  • func (re *Regexp) ReplaceAllLiteralString(src, repl string) string

Соответствует литеральным константам без преобразования.

re := regexp.MustCompile(`a(x*)b`)
fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "T"))
fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "$1"))
fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "${1}"))

Выходной результат:

-T-T-
-$1-$1-
-${1}-${1}-

о$1инструкция:

Развернуть и развернуть строку

  • func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte
  • func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte

Expand возвращает только что сгенерированный фрагмент с шаблоном, добавленным к dst. При добавлении Expand заменит переменные в шаблоне результатом, соответствующим src. match должен быть начальным и конечным индексом результата совпадения, возвращаемого FindSubmatchIndex. (обычно соответствует src, если вы не хотите использовать совпадающую позицию для другого [] байта)

В параметре шаблона переменная представлена ​​в формате:$nameили${name}, где имя — это последовательность букв, цифр и знаков подчеркивания длиной > 0. Чисто числовое символьное имя, такое как $1, используется в качестве числового индекса группы захвата; другие имена соответствуют имени именованной группы захвата, сгенерированному синтаксисом (?P...). Числовые индексы, выходящие за пределы допустимого диапазона, группы, соответствующие индексам, не совпадающим с текстом, и имена групп, не встречающиеся в регулярных выражениях, будут заменены пустыми фрагментами.

Имя переменной в формате $name, имя займет максимально длинную последовательность:$1xЭквивалентно${1x}вместо${1}x,$10Эквивалентно${10}вместо${1}0. следовательно$nameПрименимо, когда за ними следуют такие символы, как пробелы/новая строка,${name}Применяется ко всем ситуациям.

Если вы хотите вставить буквальное значение в вывод'$', можно использовать в шаблоне?.

Другие примеры

Разобрать URL

flysnowRegexp := regexp.MustCompile(`^http://www.flysnow.org/([\d]{4})/([\d]{2})/([\d]{2})/([\w-]+).html$`)
params := flysnowRegexp.FindStringSubmatch("http://www.flysnow.org/2018/01/20/golang-goquery-examples-selector.html")
// 返回[]string{}数据类型
for _, param := range params {
	fmt.Println(param)
}

Выходной результат:

http://www.flysnow.org/2018/01/20/golang-goquery-examples-selector.html
2018
01
20
golang-goquery-examples-selector