我想测试一个字符串是否包含"Kansas"
后跟" State"
以外的任何内容。
示例:
"I am from Kansas" true
"Kansas State is great" false
"Kansas is a state" true
"Kansas Kansas State" true
"Kansas State vs Kansas" true
"I'm from Kansas State" false
"KansasState" true
对于PCRE,我相信答案是:
'Kansas(?! State)'
但Mysql的REGEXP似乎并不喜欢。
ADDENDUM:感谢David M对此问题的概括: How to convert a PCRE to a POSIX RE?
答案 0 :(得分:4)
MySQL没有前瞻性。解决方法是进行两项测试:
WHERE yourcolumn LIKE '%Kansas%'
AND yourcolumn NOT LIKE '%Kansas State%'
我在这里使用LIKE
而不是RLIKE
,因为一旦你将它拆分成这样,就不再需要正则表达式了。但是,如果由于其他原因仍然需要正则表达式,您仍然可以使用相同的技术。
请注意,这与您要求的“堪萨斯州堪萨斯州”不符。
更新:如果匹配“堪萨斯州堪萨斯州”非常重要,那么你可以使用MySQL支持的这个丑陋的正则表达式:
'Kansas($|[^ ]| ($|[^S])| S($|[^t])| St($|[^a])| Sta($|[^t])| Stat($|[^e]))'
哎呀:我刚刚注意到Kip已经用一个非常类似的解决方案更新了他的评论。
答案 1 :(得分:2)
这应该有效,假设在MySQL正则表达式中允许前瞻性断言。
/Kansas(?! State)/
编辑:好的,这非常难看,但它在Perl中适用于我,并且不使用预见断言:
/Kansas(([^ ]|$)| (([^S]|$)|S(([^t]|$)|t(([^a]|$)|a(([^t]|$)|t([^e]|$))))))/
答案 2 :(得分:2)
比大型正则表达式更高效(当然,取决于您的数据和引擎的质量)
WHERE col LIKE '%Kansas%' AND
(col NOT LIKE '%Kansas State%' OR
REPLACE(col, 'Kansas State', '') LIKE '%Kansas%')
如果堪萨斯州通常以“堪萨斯州”的形式出现,你可能会发现这更好:
WHERE col LIKE '%Kansas%' AND
REPLACE(col, 'Kansas State', '') LIKE '%Kansas%'
这具有易于维护的附加优点。如果堪萨斯很常见且文本字段很大,那么它的效果就不那么好了。当然,您可以根据自己的数据测试这些数据并告诉我们他们的比较方式。
答案 3 :(得分:1)
这很难看,但是你走了:
您可能不需要将正则表达式一直扩展到最后,具体取决于您的输入是否包含“我需要让这个人在堪萨斯统计中接受手术!”
mysql> select x,x RLIKE 'Kansas($|[^ ]| ($|[^S])| S($|[^t])| St($|[^a])| Sta($|[^t])| Stat($|[^e]))' AS result from examples;
+------------------------+--------+
| x | result |
+------------------------+--------+
| I am from Kansas | 1 |
| Kansas State is great | 0 |
| Kansas is a state | 1 |
| Kansas Kansas State | 1 |
| Kansas State vs Kansas | 1 |
| I'm from Kansas State | 0 |
| KansasState | 1 |
+------------------------+--------+
7 rows in set (0.00 sec)