如何编写正则表达式捕获ProxySQL中含email或password的MySQL查询?
解决ProxySQL中MySQL查询多目标字段捕获的正则问题
需求回顾
需要匹配ProxySQL中执行的、包含email、password任意一个或两个的MySQL查询,示例包括:
SELECT email FROM user_tbl
SELECT password FROM user_tbl
SELECT col1, email FROM user_tbl
SELECT email, password FROM user_tbl
原正则^SELECT\s(.*)(email|password)(.*)FROM\suser_tbl仅能捕获第一个匹配的目标字段,无法同时捕获多个。
解决方案
1. 验证查询是否符合条件(仅判断是否包含目标字段)
如果只需要确认查询是否包含email或password,可以使用非贪婪匹配的正则,确保不会跳过目标字段:
^SELECT\s.*?(email|password).*?FROM\suser_tbl$
.*?是非贪婪匹配,避免一次性匹配到末尾,确保能命中所有目标字段的位置- 若要强制查询至少包含一个目标字段,可调整为:
^SELECT\s(?:.*?(email|password))+.*?FROM\suser_tbl$
2. 捕获所有出现的目标字段
如果需要提取查询中所有的email和password,可以分两步操作:
- 先验证查询是否符合
SELECT ... FROM user_tbl的格式 - 再从符合条件的查询中提取所有目标字段
用于提取字段的核心正则:
\b(email|password)\b
\b是单词边界,避免匹配到类似email123或passworder这类包含目标字段但并非字段名的内容
示例代码(Python)
import re # 验证查询格式的正则 query_pattern = r'^SELECT\s.*FROM\suser_tbl$' # 提取目标字段的正则 field_pattern = r'\b(email|password)\b' # 测试查询列表 test_queries = [ "SELECT email FROM user_tbl", "SELECT password FROM user_tbl", "SELECT col1, email FROM user_tbl", "SELECT email, password FROM user_tbl" ] for q in test_queries: # re.DOTALL允许匹配换行符,适配ProxySQL可能存在的换行日志 if re.match(query_pattern, q, re.DOTALL): matched_fields = re.findall(field_pattern, q) print(f"查询语句:{q}") print(f"捕获到的目标字段:{matched_fields}\n")
注意事项
- 若ProxySQL日志中的查询存在换行或多余空格,需启用正则的
DOTALL(匹配换行)模式 - 如果查询包含表别名(如
SELECT u.email FROM user_tbl u),\b(email|password)\b依然能准确匹配字段名 - 不同语言的正则引擎语法略有差异,比如JavaScript需添加
g标志开启全局匹配,才能捕获所有目标字段
内容的提问来源于stack exchange,提问作者Axen Wong
相关产品推荐
相关产品推荐

