MySQL 查询或正则表达式仅找到模式 D、E、F

Posted

技术标签:

【中文标题】MySQL 查询或正则表达式仅找到模式 D、E、F【英文标题】:MySQL query or regexp find only pattern D, E, F 【发布时间】:2014-06-06 18:24:09 【问题描述】:

我的 google-fu 让我失望了,如果有人可以为我指出正确的概念或术语方向,那就太好了。

我正在尝试从 mysql 数据库中获取行。假设我有一个等于 'DEF' 的变量。 我想以任意顺序在数据库中搜索仅包含 DEF 的记录。

示例列,

    ABC
    BC
    D
    DEX
    DEF
    DEFF
    ED
    EDF
    FED
    FEED

会回来的 D、DEF、ED、EDF、FED

【问题讨论】:

你的意思是排列吗? 'FFF` 不匹配? 为什么不用“FEED”和“DEFF”? @ÁlvaroG.Vicario 正确不匹配 @fancyPants 因为变量只有一个 E 和一个 F 问题也被标记为 php。我可以想到许多 SQL 方法来做到这一点......如果你事先知道排列。如果可以的话,我会考虑一些PHP preprocessing。 【参考方案1】:

您需要的是一个用户定义的函数来检查字符串是否匹配。这是一个:

delimiter //
create function permutes(needles varchar(255), haystack varchar(255)) returns bool
begin
    declare needles_position, first_occurance int;
    set needles_position = length(needles);
    while needles_position > 0 do
        set first_occurance = instr(haystack, substring(needles, needles_position, 1));
        if first_occurance = 0 then
            return false;
        end if;
        set haystack = (select concat(substring(haystack,1,first_occurance-1), substring(haystack,first_occurance+1)));
        set needles_position = needles_position - 1;
    end while;
    return true;
end//

现在你会得到你想要的:

select example_column from your_table where permutes(example_column ,'def');

该函数的作用是获取所有针字符并查看它们是否存在于大海捞针中。在检查下一根针之前,每根针都从大海捞针中取出,因此您不会得到双打。

【讨论】:

如果您希望区分大小写,请将第 7 行的 instr(haystack 更改为 instr(binary haystack 原谅我的无知,但是那个功能是什么语言? 它被称为结构化查询语言,又名 sql ;) 。以为我不知道它是标准的还是mysql特定的sql。你可以把它放在工作台或 phpmyadmin 中。尽管在所有已知的数据库中,创建用户定义的函数都很常见。 哈!太好了,刚刚把这个功能添加到mysql中,效果很好。 这很有效,但删除了使用“_”进行通配符搜索的能力,我尝试了一下,看看我是否能弄明白。【参考方案2】:

我将把它留在这里,即使我意识到它并不能解决问题。它将接收'FEED'。这个想法可能对其他人有所帮助。

您可以使用rlikeregex 来做到这一点:

select *
from table t
where col rlike concat('[', 'DEF', ']+')

这是在构造简单的正则表达式'[DEF]+',这就是您想要的模式。

编辑:

如果你将原始字符串分解成字符,你可以这样做:

select t.col
from table t left outer join
     (select 'D' as c union all select 'E' union all select 'F'
     ) c
     on t.col like concat('%', c.c, '%')
group by t.col
having sum(c.c is null) = 0 and 
       sum(length(t.col) - length(replace(t.col, c.c, '')) > 1);

having 子句中的第一个条件检查所有字符是否都存在。第二个没有出现不止一次。请注意,如果有重复的字母进行比较,这将不起作用。

【讨论】:

+1 我会添加 HAVING CHAR_LENGTH(col) @StanislavL ...并因“喂食”而失败【参考方案3】:

我总结了以下几种可能:

DEF
DFE
EDF
EFD
FDE
FED

REGEX (DEF|DFE|EDF|EFD|FDE|FED)


DF
DE
EF
ED
FE
FD

REGEX (DF|DE|EF|ED|FE|FD)

D
E
F

REGEX (D|E|F)

准确的查询是:

WHERE
COLUMN_NAME REGEXP '^(DEF|DFE|EDF|EFD|FDE|FED)$' OR 
COLUMN_NAME REGEXP '^(DF|DE|EF|ED|FE|FD)$' OR
COLUMN_NAME REGEXP '^(D|E|F)$'

或者:

COLUMN_NAME 
REGEXP '^(DE0,1F0,1|DF0,1E0,1|ED0,1F0,1|
          EF0,1D0,1|FD0,1E0,1|FE0,1D0,1)$'

最短的:

REGEXP '^(D(E?F?|F?E?)|E(D?F?|F?D?)|F(D?E?|E?D?))$'

DEMO

【讨论】:

这不容易扩展...如果我们需要更长的列表怎么办,例如ABCDEFG 我没有比第二部分更短的解决方案,如果是,请尝试成为您的荣誉。 很好的解析解 @dlyaza:对我来说不是核心问题,但请记住 0,1 只是 ? @Robin:我知道这一点,我想更像数学 m,n

以上是关于MySQL 查询或正则表达式仅找到模式 D、E、F的主要内容,如果未能解决你的问题,请参考以下文章

nginx 正则表达式

如何使用正则表达式找到最短的重叠匹配?

如何使用正则表达式匹配或替换仅包含数值的密码

java正则表达式

构建正则表达式模式以适应所有这些单词

MySQL REGEXP:正则表达式查询