【发布时间】:2022-01-18 14:47:37
【问题描述】:
我正在使用 PHP preg_match_all() 在 SQL 查询的 WHERE 子句中查找 SUBSTR() 函数调用。匹配应返回包括参数的函数调用以及比较运算符和比较值。示例:
SUBSTR(d.chassinummer, 7, 2) = 'CD'
在查询字符串中,来自SUBSTR() 的结果使用相等运算符或IN() 运算符进行比较。在任何查询中,通常都会有这两者的多种组合和混合组合。示例查询可能如下所示
SELECT *
FROM tbl
WHERE col_a = 'abc'
AND SUBSTR(col_b, 7, 2) = 'cd'
AND col_c LIKE 'ACD0%'
AND SUBSTR(col_d, 10, 1) IN ('A','B','C')
AND SUBSTR(col_e, 5, 3) = 'cde'
AND SUBSTR(col_f, 2, 1) IN ('C','D','E')
注意:我匹配的查询字符串中没有换行符。
我设法编写了一个几乎可以捕捉到使用等于运算符的情况的模式。看起来是这样的
preg_match_all('/substr\(.*?\) *?= *?\'.*?\'/i', $query, $matches);
但是,在给定的示例查询中,我的模式因终止匹配而失败,其中IN() 出现在以后的匹配中。在摆弄了一段时间后,我投降并寻求专家的支持。谁能帮我理解如何从给定的示例查询中提取以下匹配项
SUBSTR(col_b, 7, 2) = 'cd'SUBSTR(col_d, 10, 1) IN ('A','B','C')SUBSTR(col_e, 5, 3) = 'cde'SUBSTR(col_f, 2, 1) IN ('C','D','E')
如果将其分成两个单独的模式并使用两个 preg_match_all() 调用更容易,我觉得很好,但是如果可以在一个调用中完成,那会感觉更干净。
非常感谢。
【问题讨论】:
-
对于示例,您可以尝试使用
substr\([^()]*\)\h*(?:=\h*'[^']*'|IN\h*\([^()]*\))regex101.com/r/zv5b9C/1 但它不会考虑嵌套查询。 -
试试这个正则表达式
/substr\(.*?\)*?(:?\=|IN)*?(:?\'|\().*(:?\'|\))/giregex101.com/r/y9f52A/1