在Go语言开发过程中,处理SQL语句解析、配置文件提取等场景时,经常需要获取指定关键词后面紧跟的单词,比如提取SQL查询语句中SELECT关键字后的表名。这类需求如果用普通的字符串分割方法实现,很容易因为关键词大小写、多余空格、特殊符号等问题出现匹配错误,而使用正则表达式可以灵活应对各种复杂情况。

基础实现思路
核心思路是使用正则表达式的捕获组功能,先匹配目标关键词,再匹配关键词后面的内容。需要注意处理关键词前后的空白字符,同时明确要提取的内容的边界,避免匹配到多余字符。
正则语法说明
假设要匹配的关键词是SELECT,后面紧跟的表名由字母、数字和下划线组成,对应的正则可以写成:
(?i)bSELECTs+([a-zA-Z0-9_]+)b
其中各个部分的含义如下:
(?i):表示忽略大小写,匹配SELECT、select、Select等任意大小写组合b:单词边界,避免匹配到包含SELECT的其他单词s+:匹配一个或多个空白字符,处理关键词和表名之间的空格、制表符等([a-zA-Z0-9_]+):捕获组,匹配一个或多个字母、数字或下划线,也就是我们要提取的表名- 最后的
b:表名的单词边界,避免表名后面的其他字符被纳入匹配
完整代码示例
下面是实现匹配SQL中SELECT后表名的完整Go代码:
package main
import (
"fmt"
"regexp"
)
func main() {
// 测试用的SQL语句
sqlStr := "select * from user_info where id = 1"
// 编译正则表达式,忽略大小写,匹配SELECT后的表名
pattern := `(?i)bSELECTs+*s+FROMs+([a-zA-Z0-9_]+)b`
reg := regexp.MustCompile(pattern)
// 查找匹配结果
matches := reg.FindStringSubmatch(sqlStr)
if len(matches) > 1 {
// matches[0]是完整匹配内容,matches[1]是第一个捕获组的内容
fmt.Printf("匹配的表名是:%sn", matches[1])
} else {
fmt.Println("未找到匹配的表名")
}
// 测试更多场景
testCases := []string{
"SELECT name FROM order_list",
"select age from student_score",
"SELECT * FROM 2023_data",
"invalid sql statement",
}
for _, tc := range testCases {
matches := reg.FindStringSubmatch(tc)
if len(matches) > 1 {
fmt.Printf("SQL: %s,表名:%sn", tc, matches[1])
} else {
fmt.Printf("SQL: %s,未匹配到表名n", tc)
}
}
}
适配更多关键词场景
如果需要匹配的关键词不固定,可以把关键词作为参数传入,动态生成正则表达式:
package main
import (
"fmt"
"regexp"
"strings"
)
// 提取关键词后紧跟的单词
func getWordAfterKeyword(text, keyword string) string {
// 转义关键词中的正则特殊字符,避免正则语法错误
escapedKeyword := regexp.QuoteMeta(keyword)
// 构建正则:忽略大小写,关键词后跟一个或多个空白,再捕获后面的单词
pattern := fmt.Sprintf(`(?i)b%ss+([a-zA-Z0-9_]+)b`, escapedKeyword)
reg := regexp.MustCompile(pattern)
matches := reg.FindStringSubmatch(text)
if len(matches) > 1 {
return matches[1]
}
return ""
}
func main() {
sql1 := "UPDATE user SET name = 'test'"
sql2 := "DELETE FROM log_table WHERE time < '2024-01-01'"
sql3 = "INSERT INTO product_info (name) VALUES ('phone')"
fmt.Println(getWordAfterKeyword(sql1, "UPDATE")) // 输出 user
fmt.Println(getWordAfterKeyword(sql2, "FROM")) // 输出 log_table
fmt.Println(getWordAfterKeyword(sql3, "INTO")) // 输出 product_info
}
注意事项
- 如果关键词中包含正则特殊字符(比如
.、*等),需要使用regexp.QuoteMeta进行转义,否则会导致正则语法错误 - 如果表名可能包含其他字符(比如横杠
-),需要调整捕获组的正则范围,比如改成([a-zA-Z0-9_-]+) - 处理多行SQL语句时,可以添加
(?s)修饰符让.匹配换行符,或者先对文本做换行符替换处理 - 如果只需要匹配第一次出现的关键词,使用
FindStringSubmatch即可,如果需要匹配所有出现的位置,使用FindAllStringSubmatch
总结
使用Go的正则表达式可以高效实现关键词后紧跟单词的匹配需求,核心是通过合理的正则语法定义匹配规则,同时处理好大小写、空白字符、特殊字符转义等细节。相比字符串分割的方式,正则表达式的适配性更强,能够应对更多复杂的输入场景,在SQL解析、文本提取等场景中非常实用。