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

turn regex rule in a mysql regex rule

经过一段时间的工作和研究,我找到了一个完美的规则来检查 [batt, lk, elem] 所有单词是否都在 2 个符号“ ; 之间订单.

在下一个示例中,"sentences" 被“;”分隔,例如:

 ;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 不起作用。

我怎样才能把这个正则表达式变成一个有效的正则表达式?

谢谢

这很贵。您应该认真地努力 improve/standardize 您的数据存储以供 simpler/faster 查询。

pl.`description` REGEXP 'batt[^;]*lk[^;]*elem|[^;]*lk[^;]*elem[^;]*batt'

这假设(根据您的示例输入)elem 始终跟在 lk 之后,并且 batt 可以出现在其他两个子字符串之前或之后。

这里有一个使用变量的小技巧。

有 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;

select 只会 return id 的 1 到 6、9 和 11。

请注意,在更完整的正则表达式引擎中,它将使用 f.e 这样的模式来完成。 /;(?=[^;]*batt)(?=[^;]*lk)(?=[^;]*elem)[^;]*/i.
但是遗憾的是 MySQL REGEXP 语法不允许前瞻。