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

You*_*nse 2 php regex mysql parsing

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

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

说,它可能是

SELECT amount as `Amount: boxes` FROM t WHERE q='howdy?' and a='I\'m OK' and category=?
Run Code Online (Sandbox Code Playgroud)

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

逃逸规则赋予群众,他们中的一些依赖于当前的DB设置(NO_BACKSLASH_ESCAPES,ANSI_QUOTES和这样的),它可以把上面的查询到

SELECT amount as "Amount:boxes" FROM t WHERE q='howdy?' and a='I''m OK' and category=?
Run Code Online (Sandbox Code Playgroud)

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

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

Nik*_*kiC 7

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

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

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

/(?:
    '[^'\\]*(?:(?:\\.|'')[^'\\]*)*'
  | "[^"\\]*(?:(?:\\.|"")[^"\\]*)*"
  | `[^`\\]*(?:(?:\\.|``)[^`\\]*)*`
 )(*SKIP)(*F)| \?
/x
Run Code Online (Sandbox Code Playgroud)

preg_match_all或相匹配preg_replace_callback,取决于你想要的是什么.

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