Golang中如何使用正则表达式清理搜索文本
Golang中如何使用正则表达式清理搜索文本
我可以使用以下代码来检查文本 str 是否包含一个或全部 keys,即是否包含“MS”或“dynamics”或两者。
package main
import (
"fmt"
"regexp"
)
func main() {
keys := []string{"MS", "dynamics"}
keysReg := fmt.Sprintf("(%s %s)|%s|%s", keys[0], keys[1], keys[0], keys[1]) // => "(MS dynamics)|MS|dynamics"
fmt.Println(keysReg)
str := "What is MS dynamics, is it a product from MS?"
re := regexp.MustCompile(`(?i)` + keysReg)
matches := re.FindAllString(str, -1)
fmt.Println("We found", len(matches), "matches, that are:", matches)
}
我希望用户输入他的短语,因此我会去除不需要的单词和字符,然后按照上述方法进行搜索。
假设用户输入是:This,is,a,delimited,string,我需要动态构建 keys 变量为 (delimited string)|delimited|string,以便我可以在变量 str 中搜索所有匹配项,因此我编写了以下代码:
s := "This,is,a,delimited,string"
t := regexp.MustCompile(`(?i),|\.|this|is|a`) // 这里使用反引号包含表达式,(?i) 表示不区分大小写
v := t.Split(s, -1)
fmt.Println(len(v))
fmt.Println(v)
但我得到的输出是:
8
[ delimited string]
我的输入文本清理过程中哪部分出错了?我期望的输出是:
2
[delimited string]
这是我的playground
更多关于Golang中如何使用正则表达式清理搜索文本的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我通过下面的playground完成了它。
package main
import (
"errors"
"fmt"
"regexp"
"strings"
)
func build(words ...string) (*regexp.Regexp, error) {
// 需要排除的单词
re := regexp.MustCompile(`(?i)^(this|is|a)`)
var sb strings.Builder
switch len(words) {
case 0:
return nil, errors.New("empty input")
case 1:
return regexp.Compile(regexp.QuoteMeta(words[0]))
}
quoted := make([]string, len(words))
for i, w := range words {
quoted[i] = regexp.QuoteMeta(w)
}
sb.WriteByte('(')
for i, w := range quoted {
if i > 0 {
sb.WriteByte('\x20')
}
sb.WriteString(w)
}
sb.WriteString(`)|`)
for _, w := range quoted {
matches := re.FindAllString(w, -1)
if len(matches) == 0 {
sb.WriteString(w)
sb.WriteByte('|')
}
}
return regexp.Compile(`(?i)` + strings.TrimSuffix(sb.String(), "|"))
}
var words = regexp.MustCompile(`\pL+`)
func main() {
input := "\tThis\v\x20\x20,\t\tis\t\t,?a!,¿delimited?,string‽"
allWords := words.FindAllString(input, -1)
re, err := build(allWords...)
if err != nil {
panic(err)
}
fmt.Println(re)
str := "This is a delimited string, so let's go"
matches := re.FindAllString(str, -1)
fmt.Println("We found", len(matches), "matches, that are:", matches)
}
输出:
(?i)(This is a delimited string)|delimited|string
We found 1 matches, that are: [This is a delimited string]
更多关于Golang中如何使用正则表达式清理搜索文本的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你的正则表达式 (?i),|\.|this|is|a 匹配了逗号、句点以及单词 “this”、“is”、“a”。Split 方法会在这些匹配处分割字符串,但由于这些模式在字符串中多次出现,导致产生了空字符串元素。
具体来说,输入 "This,is,a,delimited,string" 被分割为:
""(在开头和 “This” 之前)""(在 “This” 和 “is” 之间)""(在 “is” 和 “a” 之间)"delimited""string"
因此 v 包含 ["", "", "", "delimited", "string"],长度为 5,而不是你预期的 2。输出显示为 8 是因为你的打印语句有误:fmt.Println(len(v)) 打印的是切片长度,但后续的 fmt.Println(v) 在 playground 中可能因格式化显示问题导致计数混淆。
要获得 ["delimited", "string"],你需要过滤掉空字符串。修改代码如下:
package main
import (
"fmt"
"regexp"
)
func main() {
s := "This,is,a,delimited,string"
t := regexp.MustCompile(`(?i),|\.|this|is|a`)
v := t.Split(s, -1)
// 过滤空字符串
var result []string
for _, str := range v {
if str != "" {
result = append(result, str)
}
}
fmt.Println(len(result))
fmt.Println(result)
}
或者,你可以调整正则表达式,使其更精确地匹配单词边界,避免产生空字符串:
t := regexp.MustCompile(`(?i)\b(this|is|a)\b|[,.]`)
但注意,这仍然可能产生空字符串,因为逗号分割后可能留下空元素。因此,过滤空字符串是更稳妥的方法。
对于你的搜索文本清理需求,建议先清理文本,再构建搜索模式。例如:
func cleanAndSearch(input string, searchKeys []string) {
// 清理文本:移除标点和常见单词
cleanRe := regexp.MustCompile(`(?i)\b(this|is|a)\b|[,.]`)
cleaned := cleanRe.ReplaceAllString(input, " ")
// 构建搜索正则表达式
var keysReg string
for i, key := range searchKeys {
if i > 0 {
keysReg += "|"
}
keysReg += regexp.QuoteMeta(key)
}
searchRe := regexp.MustCompile(`(?i)(` + keysReg + `)`)
matches := searchRe.FindAllString(cleaned, -1)
fmt.Println("Matches:", matches)
}
这样,你可以先清理输入文本,再使用动态构建的 keysReg 进行搜索。

