在工作和研究之后,我找到了一个完美的规则来检查[batt, lk, elem]
是否所有单词都在2个符号之间#34; ; "以任何顺序。
在下一个例子中,"句子"被"分开; "例如:
;first sentence; second sentece; third sentence;
正则表达式 - > (?=;.*batt)(?=;.*lk)(?=;.*elem)
真实例子:
; lk Buttle, batt; Probatton with LK elements; -> FOUND
;look Buttle; Proton with LK elements; -> NOT FOUND (not all 3 words are in the first OR in the second sentence)
;Brad Pitt the actor; LK elements in Battle; -> FOUND (the 3 words are in the second sentece)
;Brad Pitt the actor; LK elements in; Battle; -> not FOUND ("Battle" [root:'batt'] is in a different sentence)
将此项应用于mySQL查询时:
SELECT * FROM `table` pl WHERE pl.`description` REGEXP '(?=;.*batt)(?=;.*lk)(?=;.*elem)'
我发现 regex-lazy-operation 无效。
我怎样才能将那个正则表达式转变为一个正面的?
感谢
答案 0 :(得分:0)
这很贵。您应该认真努力改进/标准化数据存储,以便更简单/更快速地进行查询。
pl.`description` REGEXP 'batt[^;]*lk[^;]*elem|[^;]*lk[^;]*elem[^;]*batt'
这假定(根据您的示例输入)elem
始终跟随lk
,而batt
可以在其他两个子字符串之前或之后出现。
答案 1 :(得分:0)
这是一个使用变量的小技巧。
有3个单词,这意味着只有6种组合可能 因此变量以6种组合的模式开始 而替换会将其更改为为3个单词执行此操作的模式。
例如:
drop table if exists test;
create table test (id int, description varchar(100), rlikeit bool);
insert into test (id, description, rlikeit) values
(1,';lk elem batt;',true),
(2,';lk batt elem;',true),
(3,';elem lk batt;',true),
(4,';elem batt lk;',true),
(5,';batt lk elem;',true),
(6,';batt elem lk;',true),
(7,'; batt; lk; elem;',false),
(8,';batt batt batt;',false),
(9,'; lk Buttle, batt; Probatton with LK elements;',true),
(10,';look Buttle; Proton with LK elements;',false),
(11,';Brad Pitt the actor; LK elements in Battle;',true),
(12,';Brad Pitt the actor; LK elements in; Battle;',false);
set @pattern = ';x1x(2x3|3x2)|;x2x(1x3|3x1)|;x3x(1x2|2x1)';
-- set @pattern = '1x(2x3|3x2)|2x(1x3|3x1)|3x(1x2|2x1)'; -- shorter pattern
set @pattern = replace(replace(replace(replace(@pattern,
'x','[^;]*'),
'1','lk'),
'2','elem'),
'3','batt');
select *
from test
where description RLIKE @pattern;
选择只返回id 1到6,9& 11。
请注意,在一个更完整的正则表达式引擎中,它将使用类似f.e的模式完成。 /;(?=[^;]*batt)(?=[^;]*lk)(?=[^;]*elem)[^;]*/i
。
但MySQL REGEXP语法遗憾地不允许前瞻。