正则表达式爆炸sql查询

时间:2012-12-27 14:26:40

标签: php regex

我花了一整天时间搜索并找到问题的解决方案,但找不到任何问题。我有一个查询需要通过正则表达式“爆炸”。我想在where条件之后获取所选字段,表格和字段(没有检查本身)。

SELECT `a`, `b`, `c` FROM `d` WHERE `e` > 1 OR `d` > 1

我的尝试如下:

/SELECT (?<selectedFields>(,*?)\`(.*?)\`) FROM (?<tableName>\`(.*?)\`) WHERE (?<checkFields>\`(.*?)\`)/

我遇到的问题是正则表达式在where条件的第一个字段后停止。我得到的输出如下所示。

Array
(
[0] => Array
    (
        [0] => SELECT `a`, `b`, `c` FROM `d` WHERE `e`
    )

[selectedFields] => Array
    (
        [0] => `a`, `b`, `c`
    )

[1] => Array
    (
        [0] => `a`, `b`, `c`
    )

[2] => Array
    (
        [0] => 
    )

[3] => Array
    (
        [0] => a`, `b`, `c
    )

[tableName] => Array
    (
        [0] => `d`
    )

[4] => Array
    (
        [0] => `d`
    )

[5] => Array
    (
        [0] => d
    )

[checkFields] => Array
    (
        [0] => `e`
    )

[6] => Array
    (
        [0] => `e`
    )

[7] => Array
    (
        [0] => e
    )

)

我需要在相同类型的数组中使用“checkFields”获得所选字段。我究竟做错了什么?第二件事是正则表达式中的selectFields与预期的数组不一样,每个字段名都有一个数组,它用','分隔......

2 个答案:

答案 0 :(得分:4)

您不应该使用正则表达式解析sql查询,因为使用正则表达式解析sql查询与使用正则表达式解析html非常相似。 this answer清楚地说明了为什么你不应该这样做。

您最好使用一些解析器(例如this one)。

小样本:

$sql = 'SELECT `a`, `b`, `c` FROM `d` WHERE `e` > 1 OR `d` > 1';
$sqlParser = new PHPSQLParser($sql);
echo '<pre>';
print_r($sqlParser->parsed);

答案 1 :(得分:1)

使用REGEX,你不会走得太远。考虑所有可能的SQL查询:

SELECT * FROM tbl1 JOIN tbl2 
SELECT field as field2 FROM table1 as alias
etc

你需要一个解析器。尝试:http://code.google.com/p/php-sql-parser/

另外我甚至建议你根本不解析SQL,内置在数据库中的SQL解析器非常复杂并且模仿它们的行为并不容易。

如果您需要这样的行为,您可以创建一个简单的类来执行反向(构建SQL),如:

$s = new SQL();
$s->setFrom('table');
$s->addCondition('condition1','value1');
$s->select('*');  //> outputs SELECT * FROM table WHERE condition1 = 'value1'

所以你可以有一个方法来检索所有部分:

$s->getConditions();
$s->getSelect();