我正在实现一个名称过滤器,其中具有单列“filter”的表“name_filter”填充了被认为不合适的单词。当请求名称时,我想使用 *row*
匹配来检查此表中的任何名称是否包含在请求的名称中。
查询是:
SELECT filter
FROM name_filter
我当前正在拉取整个列,然后使用 std::string
的 find()
方法逐一执行检查:
// Check all names in the filter table and match if the input name contains the
// value in one of the rows
for (int i = 0; i < affectedRows; ++i) {
MYSQL_ROW row = mysql_fetch_row(result);
// No more rows
if (!row)
break;
// Content matches name filter
if (name.find(row[0]) != std::string::npos) {
mysql_free_result(result);
return false;
}
}
一位 friend 提出了以下查询,但不确定它是否正确。看起来可行,但我们之前都没有做过这样的查询:
SELECT filter
FROM name_filter
WHERE 'name'
LIKE concat('%',filter,'%')
LIMIT 1
这适用于所有情况吗?请说明为什么它适用于此查询。
理想情况下,我希望比较是一个REGEX
。虽然不是实际问题的一部分,但布朗尼指出了一个替代提案,该提案作为 REGEX
而不是 LIKE
。
REGEX 的情况是不允许像 ^bra$ 这样的短名称,但仍然允许 Cobra。
最佳答案
是的,根据documentation ,这正是您想要做的:
To find names containing a w:
mysql> SELECT * FROM pet WHERE name LIKE '%w%';
但是,与您的 c++
相比,有两个细微的差别-代码:
- 如果您的过滤器包含
null
(不是字符串'null'
,而是像null
中的c++
指针),like
找不到它,而你的c++
代码不允许这样做(因为null
被转换为空字符串''
)。 - 如果您的过滤器包含运算符
_
或%
,它们将被解释为“一个字符”和“任意数量的字符”,而string.find
不这样做。因此,如果您有一个带有z%o
的过滤器,姓名Zhro
会被禁止,因为它会匹配%z%o%
.
您当然可以利用最后一点,而不是将部分单词添加到列表中,而是添加整个搜索表达式。如果你例如添加%bra%
到您的过滤器列表,
SELECT * FROM pet WHERE 'name' LIKE filter;
然后将找到包含 bra
的任何单词。如果您添加bra%
添加到您的过滤列表中,它将禁止 bra
(和 brainiac
),但不禁止 Cobra
。如果添加bra
,这将禁止 bra
,但都不是Cobra
也不brainiac
。在您习惯之前,此列表可能会有点难以维护,但会给您带来更大的灵 active 。
您可以对 regpatterns 执行相同的操作(注意缺少 %
):
To find names containing a w, use this query:
mysql> SELECT * FROM pet WHERE name REGEXP 'w';
Regular expressions支持常用的运算符,如 ^
和$
。虽然正则表达式支持的运算符多于 like
,这两个也可以用 like
来表示不使用前导或尾随 %
。如果您的过滤词包含正则表达式运算符(例如 ^
或 .
),这些也将被解释 - 如果您将过滤器作为正则表达式输入,您可以再次利用它。
防止出现完整的单词bra
但仍然允许例如Cobra
(还有 sexy_bra
),您可以使用以下任意一项:
SELECT * FROM name_filter WHERE 'name' REGEXP '^bra$';
SELECT * FROM name_filter WHERE 'name' LIKE 'bra';
SELECT * FROM name_filter WHERE 'name' = 'bra';
最后一个不会解释运算符,因此 SELECT * FROM name_filter WHERE 'Zhro' = 'z%o';
不会true
.
关于c++ - 检查查询返回的任何行是否包含在字符串中的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42941055/