为什么会这样?
由于回溯,您仍在匹配这些句子。
因为您使用的是[^nN]
,所以它仍然可以匹配blank
或punct
。因此,这就是发生的情况(仅使用示例输入之一进行说明):
以Caffeine[:blank:]*[:punct:]*[:blank:]*[^nN]
为例(所有模式都以相同的方式运行)。
User 4: 'Caffeine-No'
^^^^^^^^ matches Caffeine literally
^ matches [:blank:] zero times
^ matches [:punct:] one time
^ matches [:blank:] zero times
^ N doesn't match `[^nN]`,let's backtrack to see if something else works
^ matches [:punct:] zero times
^ matches [:blank:] zero times
^ - matches [^nN]
Good match due to backtracking
在上面,您的正则表达式允许[^nN]
匹配-
字符。正则表达式想要匹配某项,因此它将耗尽所有可能性,直到它匹配为止(或不再存在或不再存在)。
如何解决此问题?
解决此问题的一种方法是仅在[^nN]
位置指定可能的字符(类似[0-9a-mo-z]
等),但这会很快变得复杂。更好的替代方法如下:
See the SQL working here
select * from docs where content REGEXP 'Caffeine[[:blank:]]*[[:punct:]]*[[:blank:]]*[[:<:]][^nN]'
上面的行使用[[:<:]]
断言该位置是单词边界的起点。其他语言使用\b
表示相同的含义。这意味着它可以确保除[0-9a-zA-Z_]
之外的任何字符都匹配到该位置的左侧,并且确保[0-9a-zA-Z_]
中的任何字符都可以匹配到该位置的右侧。
在其他正则表达式引擎中,可以通过使用所有格修饰符(通常是+
之后的.*+
,例如|--------------------------------------------|------------------|
| Column 1 | column 2 |
|--------------------------------------------|------------------|
|/fixed/sample_1 | 10 |
|--------------------------------------------|------------------|
|/fixed/sample_1/ | 15 |
|--------------------------------------------|------------------|
|/fixed/sample_1/sp1_level2 | 10 |
|--------------------------------------------|------------------|
|/fixed/sample_1/sp1_level2/sp1_level3 | 20 |
|--------------------------------------------|------------------|
|/fixed/sample_2/ | 25 |
|--------------------------------------------|------------------|
|/fixed/sample_2/sp2_level2/sp2_level3 | 20 |
|--------------------------------------------|------------------|
|/fixed/sample_3 | 30 |
|--------------------------------------------|------------------|
)来轻松实现相同的目的,但是MySQL尚无所有格令牌(AFAIK)。
,
不是试图猜测所有可能的变化,而是最简单的方法是剥离“咖啡因”和所有不是单词字符的内容,然后使用其余的内容。使用POSIX [:alnum:]
(alphanumeric) character class并将其取反。
select regexp_replace(answer,'^Caffeine[^[:alnum:]]+','')
from quiz;
dbfiddle
然后解析剩余的内容。
本文链接:https://www.f2er.com/3157197.html