使用正则表达式解析SQL,不包括带引号的文字

时间:2014-03-08 07:09:29

标签: php mysql regex parsing

对于我的DBAL,我需要解析所提供的SQL [mysql dialect,特别是]字符串以查找所有占位符。

但是,当然,我不想解析任何类似占位符的组合,偶尔也可能出现在引用的文字中 - 单引号或双引号或反引号引用。

说,可能是

SELECT amount as `Amount: boxes` FROM t WHERE q='howdy?' and a='I\'m OK' and category=?

只有最后一个问号是唯一的实际占位符

鉴于大量的转义规则,其中一些取决于当前的数据库设置(NO_BACKSLASH_ESCAPESANSI_QUOTES等),这可以将上述查询转换为

SELECT amount as "Amount:boxes" FROM t WHERE q='howdy?' and a='I''m OK' and category=?

我怀疑这项任务是否可行。

然而,我仍然希望可以做到,甚至可能有人手头有解决方案。

1 个答案:

答案 0 :(得分:7)

您正在寻找的一般模式是/string(*SKIP)(*F)|\?/,其中string是匹配字符串的正则表达式。我对SQL字符串语法并不熟悉。一些建议:

  • 带反斜杠转义的单引号:'[^'\\]*(?:\\.[^'\\]*)*'
  • 引号重复转义的单引号:'[^']*(?:''[^']*)*'

E.g。带有反斜杠和重复转义的单引号,双引号和反引号的完整正则表达式可能如下所示:

/(?:
    '[^'\\]*(?:(?:\\.|'')[^'\\]*)*'
  | "[^"\\]*(?:(?:\\.|"")[^"\\]*)*"
  | `[^`\\]*(?:(?:\\.|``)[^`\\]*)*`
 )(*SKIP)(*F)| \?
/x

将其与preg_match_allpreg_replace_callback相匹配,具体取决于您想要的内容。

注意:为了避免额外的转义,请将正则表达式放在NOWDOC字符串中。