MySQL REGEXP字边界[[:<:]] [[:>:]]和双引号

时间:2013-09-19 17:52:33

标签: mysql regex word-boundary

我正在尝试将一些全字表达式与MySQL REGEXP函数匹配。如果涉及双引号,则存在问题。

MySQL文档说:“要在正则表达式中使用特殊字符的文字实例,请在其前面加上两个反斜杠()字符。”

但这些查询都返回0:

SELECT '"word"' REGEXP '[[:<:]]"word"[[:>:]]';             -> 0
SELECT '"word"' REGEXP '[[:<:]]\"word\"[[:>:]]';           -> 0
SELECT '"word"' REGEXP '[[:<:]]\\"word\\"[[:>:]]';         -> 0
SELECT '"word"' REGEXP '[[:<:]] word [[:>:]]';             -> 0
SELECT '"word"' REGEXP '[[:<:]][[.".]]word[[.".]][[:>:]]'; -> 0

我还能尝试获得1?或者这不可能吗?

4 个答案:

答案 0 :(得分:20)

让我先引用documentation

  

[[:&lt;:]],[[:&gt;:]]

     

这些标记代表字边界。他们匹配开头和   词尾,分别。一个单词是一系列单词字符   不在单词字符之前或之后的单词字符。一个字   character是alnum类中的字母数字字符或   下划线(_)。

从文档中我们可以看到问题背后的原因,并不是由于逃避而造成的。问题是你试图匹配字符串开头的单词边界[[:<:]],这将无效,因为你可以从文档中看到的单词边界将单词字符与非单词字符分开,但在你的情况下,第一个字符是",它不是单词字符,所以没有单词边界,最后一个"[[:>:]]也是如此。

为了使其正常工作,您需要将表达式稍微更改为此表达式:

"[[:<:]]word[[:>:]]"
 ^^^^^^^    ^^^^^^^

注意单词边界如何将非单词字符"与开头的单词字符w分隔开来,并在字符串末尾从"分隔d

编辑:如果你总是想在字符串的开头和结尾使用单词边界而不知道是否会有实际的边界,那么你可以使用下面的表达式:

([[:<:]]|^)"word"([[:>:]]|$)

这将匹配开头的字边界或字符串开头^,并且对于字边界或字符串结尾的结尾相同。我真的建议你研究你想要匹配的数据并寻找常见的模式,如果它们不是正确的工具,就不要使用正则表达式。

SQL Fiddle Demo

答案 1 :(得分:3)

在MySQL 8及更高版本中

添加到Oleksiy Muzalyev的答案

https://dev.mysql.com/doc/refman/8.0/en/regexp.html#regexp-compatibility

在MySQL 8.04及更高版本中,您必须使用:

\bword\b

其中\b代表字边界的ICU变体。以前的Spencer库使用[[:<:]]来表示单词边界。

当实际使用它作为查询的一部分时,我不得不对转义字符\进行转义,因此我的查询实际上看起来像

SELECT * FROM table WHERE field RLIKE '\\bterm\\b'

从PHP查询时,请使用单引号进行相同的操作

$sql = 'SELECT * FROM table WHERE field RLIKE ?';
$args = ['\\bterm\\b'];
...

答案 2 :(得分:1)

在MySQL从8.04开始使用:\\ bword \\ b

参考https://dev.mysql.com/doc/refman/8.0/en/regexp.html#regexp-compatibility

答案 3 :(得分:0)

您需要更加精巧:

SELECT '"word"' REGEXP '"word"';                                      --> 1
SELECT '"This is" what I need' REGEXP '"This is" what I need[[:>:]]'; --> 1

也就是说,

如果测试字符串以“字母”开头/结尾,则在字符串之前/之后加上[[:<:]] / [[:>:]]

这与将它们盲目地钉在弦上相反。毕竟,您已经在搜索字符串中查找特殊的正则表达式字符以对其进行转义。在这方面,这只是另一项任务。 “字母”的定义应与所需的单词边界标记相匹配。