在 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 语法不允许前瞻。
经过一段时间的工作和研究,我找到了一个完美的规则来检查 [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 语法不允许前瞻。