php - 在 php 中使用正则表达式解析 WHERE 子句

标签 php mysql regex

我需要从“WHERE”子句中检索表父子关系,如下所示:

select ... large list of fields with aliases ...
from ... list of joined tables ...

where ((`db_name`.`catalog`.`group` = `db_name`.`catalog_group`.`iden`) 
and (`db_name`.`catalog`.`iden` = `db_name`.`catalog_sub`.`parent`))

是否有一些正则表达式可以从每个条件中获取标识符?假设在数组中,element[0] = 从左侧开始的表格,element[1] 是从右侧开始的表格。 Ident 的名称可以是任何名称。因此,只有像“where”、“and”、“=”这样的 SQL 运算符才可以作为键。

任何帮助将不胜感激。

澄清

我不想从 WHERE 子句获取引用。我只是想要这样的引用。所以我可以看到可能有正则表达式来替换所有序列

`.` 

. 

然后通过

匹配所有反引号对
` @ ` = ` @ `

默认情况下,标识符周围的反引号始终出现在任何可能的查询中。默认情况下,所有字符串值都用双引号引起来。我认为这对于正则表达式大师来说并不是一项复杂的任务。提前致谢。

PS这是因为myISAM引擎不支持我强制手动恢复的引用。

结束于:

public function initRef($q) {

    $s = strtolower($q);
    // remove all string values within double quotes
    $s = preg_replace('|"(\w+)"|', '', $q); 
    // split by 'where' clause
    $arr = explode('where', $s); 
    if (isset($arr[1])) { 
        // remove all spaces and parenthesis
        $s = preg_replace('/\s|\(|\}/', '', $arr[1]); 
        // replace `.` with .
        $s = preg_replace('/(`\.`)/', '.', $s);
        // replace `=` with =           
        $s = preg_replace("/(`=`)/", "=", $s); 
         // match pairs within ticks
        preg_match_all('/`.*?`/', $s, $matches);
        // recreate arr
        $arr = array();
        foreach($matches[0] as &$match) {
            $match = preg_replace('/`/', '', $match); // now remove all backticks
            $match = str_replace($this->db . '.', '', $match); // remove db_name
            $arr[] = explode('=', $match); // split by = sign
        }
        $this->pairs = $arr; 
    } else {
        $this->pairs = 0;
    }

}

最佳答案

使用正则表达式似乎对您没有帮助。如果有子查询怎么办?如果您的查询包含一个带有文本“WHERE”的字符串怎么办? Hakre 在上面的评论中提到了这一点,但最好的选择实际上是使用可以实际解释 SQL 的东西,以便您可以找到什么是真正正确的 WHERE 子句,什么不是。

如果您坚持以“错误”的方式执行此操作,而不是使用某些上下文感知解析器,则必须找到 WHERE 子句,例如如下所示:

$parts = explode('WHERE', $query);

假设您的查询中只有一个 WHERE 子句,则 $parts[1] 将包含从 WHERE 开始的所有内容。之后,您必须检测可能跟随的所有有效子句,例如 ORDER BY、GROUP BY、LIMIT 等,并在那里断开字符串。像这样的事情:

$parts = preg_split("/(GROUP BY|ORDER BY|LIMIT)|/", $parts[1]);
$where = $parts[0];

您必须检查文档以了解您的 SQL 风格以及您想要支持的查询类型(SELECT、INSERT、UPDATE 等),以获得您想要拆分的关键字的完整列表。

之后,删除所有括号可能会有所帮助,因为优先级与您的问题无关,并且它们使解析变得更加困难。

$where = preg_replace("/[()]/", "", $where);

从那时起,您必须再次拆分才能找到所有单独的条件:

$conditions = preg_split("/(AND|OR|XOR)/", $where);

最后,您必须拆分运算符才能获得左右值:

foreach ($conditions as $c)
{
    $idents = preg_split("/(<>|=|>|<|IS|IS NOT)/");
}

您必须检查该运算符列表并在需要时添加到其中。 $idents 现在包含所有可能的标识符。

您可能需要注意,其中几个步骤(至少最后一步)还需要修剪字符串才能正常工作。

免责声明:再说一遍,我认为这是一个非常糟糕的主意。该代码仅在只有一个 WHERE 子句时才有效,即使如此,它也取决于很多假设。复杂的查询可能会破坏此代码。请改用 SQL 解析器/解释器。

关于php - 在 php 中使用正则表达式解析 WHERE 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18338269/

相关文章:

javascript - 是否存在允许正则表达式的 JavaScript 的 String.indexOf() 版本?

php - php 中的 new DateTime() 与 new DateTime ('NOW' )

php - ST_WITHIN() 不返回任何结果

javascript - 如何在一个php文件上显示数据库中的不同内容?

c# - 使用正则表达式从字符串中提取子字符串

javascript - 匹配 float 模式的正则表达式

php - 使用 Mailchimp 的 API v3 将订阅者添加到列表

PHP/SQL - 无法打开流 : No such file or directory

mysql - 如何在 cloudflare 中使用页面规则阻止 url?

python - 当 session.flush() 在 SQLAlchemy 上失败时,我应该调用回滚吗?