【问题标题】:Regex: extracting valid table names and columns from an MySQL query正则表达式:从 MySQL 查询中提取有效的表名和列
【发布时间】:2015-02-12 11:56:36
【问题描述】:

我正在尝试从任何给定的 MySQL 查询中匹配并提取所有表名和列。

给定的查询不加引号(反引号),根据 MySQL 的命名规则是:

不带引号的标识符中允许的字符:

ASCII:[0-9,a-z,A-Z$_](基本拉丁字母,数字 0-9,美元,下划线)

扩展:U+0080 .. U+FFFF

对于一个测试用例,我正在使用这个查询:

SELECT  users.id , users.first_name ,users.last_name,  roles.role,avatars.img_name,timezone.gmt_offset
FROM  users 
LEFT JOIN roles ON  users.role = roles.id 
LEFT JOIN  avatars ON users.avatar=avatars.id 
LEFT JOIN country ON users.country=country.country_code 
LEFT JOIN  timezone ON users.timezone = timezone.id 
WHERE (users.id >=2 AND  users.id <=4 ) OR (roles.role LIKE  'us%')
OR (roles.role =  'user(complex.sit )' && (timezone.gmt_offset >=7200
OR  users.last_name ='tryme'))
LIMIT 0 , 30

到目前为止我的正则表达式:

%[ .(),]?([a-z0-9_$]{2,})[ .(),]?(?!AND|OR|LIKE|SELECT|JOIN|ON)%i

我正计划捕获该组并将其替换为带有反引号的匹配换行问题是我也无法过滤掉正在匹配的保留字(SELECT,JOIN ....),我尝试添加一个否定的前瞻,但它不起作用。

第二个问题是示例= 'user(complex.sit )' 中的值,我不希望它与这两个词匹配(复杂的坐姿)。

有什么建议吗?

【问题讨论】:

    标签: mysql regex


    【解决方案1】:

    %g 全局修饰符与表达式一起使用:

    %[\s.(),]+?([a-z\d_$]{2,})[\s.(),]*?(?:AND|OR|LIKE|SELECT|JOIN|ON|)%g
    

    【讨论】:

    • 在我发布之前玩过它,它会从timezone 中删除“on”等等...我不知道为什么结果很奇怪,大多数表名都不匹配
    • 当我将 %g 与表达式一起使用时,我得到的结果为:regex101.com/r/dY3bG4/1
    • g 代表全局吗?你得到的结果与我电脑上的结果相似,但 complexsit 仍然匹配我需要避免它们,因为它们是值而不是表名或列
    • 没错……所有可以反引号的名字
    • 您还会注意到,当您添加 i 分隔符或 A-Z 时,它会停止工作,并且不再转义这些单词。
    【解决方案2】:

    还有一个形式的问题,“我如何使用正则表达式(宿主语言 YYY)操作 XXX 语言的一些小程序?”潜在的问题是,“我如何解析使用正则表达式的语言 XXX 的程序?”正确答案几乎总是,不要

    你正在走上流泪的道路。正则表达式的设计目的是解析除了最琐碎、有限的语言之外的任何语言。您可能会找到一个满足您当前需求的正则表达式,但是当另一个需求出现时,您就碰壁了。正则表达式变得越来越长,变得无法理解,更不用说维护了。

    要解析语言,使用解析器。在这个时间点上,毫不夸张地说,几乎所有平台上的几乎所有语言都有解析器。

    我不知道您使用的是什么语言/平台,所以我不会推荐任何特定的解析器,但是对“JavaScript SQL 解析器”的查询立即提出了这个问题:https://www.npmjs.com/package/simple-sql-parser。只是作为一个例子。

    【讨论】:

    • 嗨,谢谢,我完全同意,但我没有在这里解析语言 - 我完成了处理编写高级查询的新 (PHP) 数据库类 - 这只是我想知道它是否可能- 主要原因不是为了验证查询,而是为了处理不带引号和带引号的命名规则。
    • 使用正则表达式解析任何东西都是完全有效的,因为用例可能使其合法化。对简单的任务使用损坏的解析器并不是正确的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多