我有一个带有名字的数组和一个带有全名的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结合使用呢?先感谢您!
答案 0 :(得分:2)
但是如何将其与implode结合使用呢?
会给我一个像
\[John\]\|\[Brian\]
这样的字符串。但这不是我想要的。
这是预期的行为,因为“|
”是一个正则表达式元字符。因此,请先逃避$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).") '";
SELECT full_names FROM myTable
WHERE full_names REGEXP '^(\\[John\\]|\\[Brian\\]) '
[John] Mclay
[John] Rossi
[Brian] Cosby
答案 1 :(得分:0)
在将names_array发送到内爆帮助之前,是否使用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);