我试图解析一个“插入”MySQL数据库查询,该查询可能如下所示:
insert into tablename (field1, field2, field3) values ('te\'s ,, t', 3, "OO,\"P")假设:查询始终是“合法的”/没有错误。
规则:
tablename之后2-字段名可以包含[a-z0-9_],它是总是,后面跟着空格或昏迷[, ]。可能有很多空格,或者只有一个或零。
出于某些原因,它不起作用:我问:“在第一个括号后查找所有1-100个字符的单词,这些单词后面可能有一个或多个昏迷或空格:
preg_match_all( 'tablename \((\w{1,100}(?:[, ])*)+\) values/si', $matches, $allfields );我尝试在PHP中运行一个preg_match_all(),它只返回最后一个字段。我遗漏了什么?
发布于 2015-06-17 00:41:39
首先:顺便说一下,尝试用简单/天真的文本方法解析像SQL这样复杂的语言是个坏主意。
关于您的特定问题,您的模式无法工作,因为您正在尝试从重复捕获组中提取数据。当您重复一个捕获组时,前面的捕获总是被下一个覆盖,依此类推。
这样做的模式更为复杂。这是一个经典的问题:如何提取两个子字符串之间的几个事物(重复的事物)?
要做到这一点,需要使用与前面结果末尾的位置匹配的\G锚点。(注意:在开始时,由于没有先前的结果,所以\G锚点匹配字符串的开头。为了避免这种情况,您必须使用负的(?!\A),以确保字符串的开始将失败。)
(?:\G(?!\A)\s*,|insert\s+into\s+tablename\s*\()\s*\K\w+模式细节:
(?: # non capturing group with the two possible beginings
\G(?!\A) \s* , # contigous to the previous match, spaces, comma
| # OR
insert\s+into\s+tablename\s*\( # the branch for the first result
)
\s*
\K # discard all characters on the left from whole match result
\w+ # the field name当到达最后一个字段时,由于只有一个结束括号而没有逗号,所以连续性被打破了。所以\G不会再成功了。
发布于 2015-06-17 00:43:32
你需要使用Regex吗?
为此,我将使用PHP自己的字符串函数。
查找开始和结束括号的位置:
$start = strpos( $sqlQuery, "(" )
$stop = strpos( $sqlQuery, ")" )然后使用以下内容提取字段名部分:
$names = substr($sqlQuery, $start, $stop - $start )然后,您可以爆炸结果,得到每个字段名的数组:
$nameParts = explode($names, ",")https://stackoverflow.com/questions/30880409
复制相似问题