【问题标题】:Escape square brackets while use REGEXP and IMPLODE使用 REGEXP 和 IMPLODE 时转义方括号
【发布时间】:2015-09-17 16:35:41
【问题描述】:

我有一个带有名字的数组和一个带有全名的 mysql 表上的列(名字有时在方括号中)。正确的 mysql 语句如何比较数组的元素和列的元素并仅在第一个名称在数组中并且也在方括号中时才返回全名?

   id      |      full_names

-----------------------------------
    1       |   [John] Mclay
    2       |   [John] Rossi
    3       |   Will John
    4       |   [Brian] Cosby
    5       |   Brian O'neal
$names_array=array("[John]" ,"[Brian]");

sql_query="SELECT full_names FROM myTable
              WHERE full_names REGEXP '^(".implode("|", $names_array).")[[:>:]]'"; 

因此,我希望只有第一个、第二个和第四个全名。 我的问题是因为方括号。数组中的每个名称都有 2 个方括号,对于每个名称,我必须使用 \\ 两次来转义特殊字符。但是我怎样才能把它和内爆结合起来写呢?先感谢您!

【问题讨论】:

  • 使用preg_quote 转义元字符。另外,请将问题标记为php
  • $impl_string=implode("|", $names_array); 会给我这样的字符串:[John]|[Brian]preg_quote(impl_string,'\\') 会给我这样的字符串 \[John\]\|\[Brian\]。但这不是我想要的。
  • 使用preg_quote 之前 implode,因为@gyaani 已经回答了

标签: php mysql regex


【解决方案1】:

但是如何结合 implode 来编写它?

会给我一个像\[John\]\|\[Brian\] 这样的字符串。但这不是我想要的。

这是预期行为,因为“|”是一个正则表达式元字符。所以转义$names_array first中的正则表达式元字符:

// Loop the array and escape each item with preg_quote
foreach($names_array as $index => $name) {
    $names_array[$index] = preg_quote($name);
}

但是,为了将它作为字符串传递给 MySQL,您还需要转义反斜杠和单引号。我们可以在这里使用str_replace

// Escape backslashes and single quotes for SQL
$names_array = str_replace( array("\\","'"), array("\\\\","\\'"), $names_array);

注意:这应该使用mysqli_real_escape_string来完成。 这只是这个问题的范围。

现在,我们可以终于添加管道以进行交替。


您还有一件事要纠正。您正在使用POSIX word bounday[[:>:]],它匹配前面有单词字符但后面没有单词字符的位置。但是,“]不是单词字符。所以它与你的例子不符。

如果您想检查名称后是否有空格“”,只需将其放入您的模式中:

$sql_query="SELECT full_names FROM myTable
              WHERE full_names REGEXP '^(".implode("|", $names_array).") '";
                                                                        ^
                                                                 (here) ^

代码:

$names_array = array("[John]" ,"[Brian]");

// Loop the array and escape each item with preg_quote
foreach($names_array as $index => $name) {
    $names_array[$index] = preg_quote($name);
}

// Escape backslashes and single quotes for SQL
$names_array = str_replace( array("\\","'"), array("\\\\","\\'"), $names_array);

// Now you can add "|"s that won't be escaped
$sql_query="SELECT full_names FROM myTable
              WHERE full_names REGEXP '^(".implode("|", $names_array).") '";

Run this code here

$sql_query 的值:

SELECT full_names FROM myTable
              WHERE full_names REGEXP '^(\\[John\\]|\\[Brian\\]) '

MySQL查询结果:

[John] Mclay
[John] Rossi
[Brian] Cosby

Test in SQL Fiddle

【讨论】:

    【解决方案2】:

    在将 names_array 发送到 implode 帮助之前,是否使用类似 array_map 的东西修改了 names_array?

    未经测试的示例:

    $names_for_regex = array_map(function($name){
         return preg_quote($name) ; // the next statement might be more suitable
         return '('.preg_quote($name).')' ;
    }, $names);
    

    【讨论】:

    • 无需分组。第一个函数行看起来有效
    猜你喜欢
    • 2011-08-17
    • 1970-01-01
    • 2017-01-26
    • 2015-09-25
    • 1970-01-01
    • 2011-07-07
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多