php - 使用 REGEXP 和 IMPLODE 时转义方括号

标签 php mysql regex

我有一个包含名字的数组和一个带有全名的 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 个方括号,对于每个名称,我必须使用 \\ 两次来转义特殊字符。但是如何将它与 implode 结合起来写呢?先感谢您!

最佳答案

But how can I write it in combination with implode?

will give me a string like this \[John\]\|\[Brian\]. But this is not what I want.

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

// 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

关于php - 使用 REGEXP 和 IMPLODE 时转义方括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32635537/

相关文章:

php - 将对象作为 json 返回时访问 Eloquent 关系

regex - Ansible 正则表达式环顾四周无法替换模式

php - 如何禁用特定模块的错误 Controller

php - Laravel Auth::attempt 每次都失败

MySQL:在列列表中使用 COUNT(column_name),并在 HAVING 子句中再次使用。这是否会导致 COUNT(column_name) 操作运行两次?

php - 无效查询或字符类型

javascript - 如何使用mysql在网站中添加谷歌地图

javascript - 匹配 ("Hi") 但不匹配 (文本 ("Hi"))

php - 用于验证 ip-list 中的 ip-range 的正则表达式

php - 拾色器不保存值