在mysql正则表达式规则中转为正则表达式规则

时间:2017-06-10 14:08:12

标签: mysql regex regex-lookarounds regex-greedy

在工作和研究之后,我找到了一个完美的规则来检查[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 无效。

我怎样才能将那个正则表达式转变为一个正面的?

感谢

2 个答案:

答案 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语法遗憾地不允许前瞻。