1

我正在尝试制定正则表达式(我对此几乎没有经验)来检查 sql 语句中是否存在一个字符串(“WHERE”),但前提是它不存在于括号之间。

我正在使用 PHP,并会感谢代码或帮助。

我会发布我尝试过的代码,但实际上甚至不知道从哪里开始。我试图使用其他方法来达到预期的效果,但一直遇到一个或另一个问题。

我正在尝试基于一堆搜索条件构建一个 SQL 语句,并且在每个可能的搜索字段中,我需要确定天气以在 where 比较之前的 sql 语句中放置“WHERE”或“&&”。

我通过使用 strstr 一段时间来做到这一点,但随后不得不向 sql 的“SELECT”部分添加一个子查询,这需要使用“WHERE”,所以这显然搞砸了我的方法。

任何提示都会很棒。

编辑:

声明的开头:

SELECT `t1`.*, (SELECT COUNT(`eta`.`time_away`) FROM `table2` WHERE `table2`.`field` = '1') as `time_away`
FROM `table1` `t1`
LEFT JOIN `table3` `t3` ON `t1`.`id` = `t3`.`t3id`

然后我有各种条件可以添加 WHERE 语句,例如:

if ($this === true) {
  ### CHECK HERE TO SEE IF WHERE EXISTS, BUT NOT THE WHERE WITHIN THE SUBQUERY
  if ($sql does not contain WHERE outside of subqueries) {
    $sql .= " WHERE ";
  } else {
    $sql .= " && ";
  }
  $sql .= ""; // add my condition here
}

这显然对于一个条件来说是多余的,但是我的脚本会有很多,并且在第一个条件之后的那些中,这将是非常必要的。

4

2 回答 2

2

删除 () 中的所有内容并在 sql 命令的左侧搜索 WHERE 子句:

<?php
$string = 'select * from (select * from a where a.id=x) where id=y';
$pattern = '/\(.*\)/';
$replacement = '';
echo preg_replace($pattern, $replacement, $string);
?>

将打印:

select * from where id=y

现在您可以进行正常的“位置搜索”了。

于 2013-07-24T20:10:09.587 回答
1

You can try this test:

if (preg_match('~(?>(?>[^()w]+|\Bw+|\bw(?!here\b))+|(\((?>[^()]++|(?-1))*\)))*\bwhere\b~i',
               $string, $match)) {
    /* what you have to do */
}

The advantage of this solution is that it can deal with nested parenthesis and avoid to miss some content, when other ways will fail, example:

xxxxxxxxxxxxx (sdfs(df df)g df) WHERE (sdfsdfdsfsdfsdf) xxxxxxxxxxxxxxx 

Pattern details:

(?>                    # open the first non capturing group (* atomic)
    (?>                # open the second non capturing group
        [^()w]+        # all characters except ( ) w, one or more times 
      |                # OR
        \Bw+           # some w preceded by a word character (ie: a-zA-Z0-9_)
      |                # OR
        \bw(?!here\b) # some w not preceded by a word character
                       # and not followed by "here"
    )+                 # close the second group and repeat 1 or more times
  |                    # OR
    (                  # open the first capturing group
        \(             # literal (
        (?>            # open the third non capturing group
            [^()]++    # all characters except ( ), one or more times (* possessive)
          |            # OR
            (?-1)      # repeat the last capturing group
        )*             # close the third non capturing group
                       # and repeat it zero or more times
        \)             # literal )
    )                  # close the thirst capturing group
)*                     # close the first non capturing group
                       # and repeat 0 or more times
\bwhere\b              # "where" not followed and not preceded by a word character

The goal of this pattern is to match all that is possible until the word "where" outside parenthesis.

于 2013-07-24T20:21:03.327 回答