MySQL模糊查询/模式匹配(Pattern Match)

news2024/10/7 10:24:56

      使用SQL查询数据时,时常会遇到这种情况,我们并不需要精确的匹配,而是要查找具有某类特点的数据。这种场景我们就要用到模糊查询。MySQL中常用的模糊查询方法有2种:

  • like语句模糊查询
  • regexp正则表达式模式匹配

目录

一、使用like模糊匹配

二、使用正则表达式模式匹配

2.1 普通匹配

2.2 位置匹配

2.3 特定次数匹配

2.4 特定模式匹配

2.5 修改匹配的数据


、使用like模糊匹配

当只需要进行简单模糊查询时,可以利用like语句完成,like可以用来模糊匹配字符串。

like语句的语法是:expr [not] like 'pattern'。expr可以是我们的数据列或者某种表达式,pattern就是我们想要查询的数据具有的模式。在'pattern'中,可以使用'_'来匹配单个字符或'%'来匹配任意字符串(包含空字符,但不会匹配null)。

下面用一个示例来演示like用法,先建立一张测试表:

create table test(
id int not null primary key,
value varchar(32));

insert into test values(1,'abc'),(2,'abcd'),(3,'abc123'),(4,'ab123xyz');

查询和abc有关的数据:

select * from test;

select * from test where value like 'abc';

  • 当模式中没有_或%时,like会只用精确匹配(相当于=),这里只有abc了被匹配出来。

使用_匹配单个字符(包含空字符,但不会匹配null):

select * from test where value like 'abc_';

这里的模式是'abc_',使用_匹配单个字符,只有abcd被匹配了出来。

使用%匹配任意字符:

select * from test where value like 'abc%';

当使用%,匹配包含空字符在内的所有字符串。

使用not like反向匹配,即所有符合模式的都不查询出来:

select * from test where value not like 'abc%';

这里所有以abc开头的字符串都不会显示出来。

上面的例子都是以查找以abc开头的示例,_和%可以出现在模式的任何地方。需要注意的一点是,如果匹配的字段上有索引,如果遇到'%str'这种将%放在模式开头,那么将会导致索引失效,使用中需要斟酌一下性能。

二、使用正则表达式模式匹配

like 匹配的方式可以完成一些简单的模糊查询,例如你可以用%abc%来匹配任意包含abc的数据,但是如果问题换成:包含a或b或c,那么你就要写3次匹配,如果问题更复杂一点(例如匹配特定次数),like可能就无法完成了,此时你就需要采用正则表达式匹配。

正则表达式是一个包含文本和特殊字符的字符串,利用它可以识别各种复杂模式的字符串。MySQL可以通过regexp或rlike(这两个是同义词)操作符来完成正则表达式的匹配,语法和like一样 expr [not] regexp 'pattern'。

正则表达式的匹配结果,如果成功则返回1,失败返回0,用在where条件中分别对应真/假:

select 'abcd' regexp 'abc';

select 'abcd' regexp '123';

下面演示几类最常用的正则表示式匹配场景,我们先将测试数据换成更复杂内容:

truncate table test;

insert into test values(1,'abc'),(2,'abcd'),(3,'abc 1'),(4,'abc1,xkz'),(5,'abc13'),(6,'xyzABC123'),(7,'xyzabc1223'),(8,'123456'),(9,'1212123xyzabc');

commit;

测试数据如下:

select * from test;

2.1 普通匹配

普通匹配和like类似,直接输入字符串,则会匹配出包含改字符串的值:

select * from test where value regexp 'abc';

  • regexp 'abc' 相当于like '%abc%',所有包含abc的都匹配的出来,除了id为8的纯数字。

反向匹配,可以直接在regexp 前加上not,或者整体取反:

select * from test where value not regexp 'abc';

select * from test where not(value regexp 'abc');

  • expr not regexp … 和 not (epxr regexp …)两种写法是等效的

2.2 位置匹配

某些时候我们需要从特定的位置开始匹配,正则表达式可以通过^和$来指定匹配的位置:

  • ^ 代表从开头进行匹配
  • $ 代表从结尾进行匹配

匹配以'xyz'开头的数据

select * from test where value regexp '^xyz';

匹配以'23'结尾的数据

  • (23)的小括号表示这是一个整体

2.3 特定次数匹配

有些时候我们想知道某种模式出现的次数,这时我们就需要用到次数匹配了,常用的次数匹配模式如下:

  • […]   匹配方括号出现的任意字符
  • .       匹配任意单个字符
  • *      匹配前面模式0次或多次
  • +     匹配前面模式1次或多次
  • ?    匹配前面模式0次或1次
  • {m}  匹配前面模式m次
  • {m,n} 匹配前面模式m到n次

匹配包含字符串'k'或者'5'的数据:

select * from test where value regexp '[k5]';

匹配x和z中间包含一个字符的模式:

select * from test where value regexp 'x.z';

匹配以abc开头,后面跟任意字符

select * from test where value regexp '^abc.*';

  • .* 代表任意字符出现任意次数,可以匹配任何字符,这里去掉效果也是一样的

匹配abc1之后,出现1次或多次2的数据:

  1. select * from test where value regexp 'abc12+';

  • abc12+,+代表前面的2出现1次或多次

匹配abc1之后,出现0次或1次2的数据:

select * from test where value regexp 'abc12?';

  • 注意和上个例子区别,?代表0次或1次,因此只要含abc1就会匹配出来
  • id为7的数据,结尾1223,满足了出现1次2,所以也被查了出来

查询abc1之后,2出现2次的数据:

select * from test where value regexp 'abc12{2}';

  • 只要2出现2次即视为满足条件,如果出现更多次数的2,依然是满足的(并不管后续数据,只要匹配到2次就判定成功)。

查询包含6个数据的数据:

select * from test where value regexp '[0-9]{6}';

  • [0-9]代表数字1到9任意数字,{6}代表重复6次,只要有6个连续的数字即满足条件。

查询仅包含6个数字的数据:

select * from test where value regexp '^[0-9]{6}$';

  • 我们把上个模式用^和$限制起来,代表从开头到结尾,只有6数字,id为9的数据(数字后包含字符串)就不匹配了。

查询'12'重复1到2次的数据:

select * from test where value regexp 'abc(12){1,2}';

  • (12)用括号括起来代表一个整体
  • {1,2} 代表匹配1次或2次,只要满足即可以。

2.4 特定模式匹配

MySQL还提供了一些特殊字符串来表示某一类字符,其格式是[:character_class:],常用的类别有:

  • [:digit:] 表示所有数字
  • [:alpha:] 表示所有字符
  • [:alnum:] 表示所有数字和字符
  • [:blank:] 表示空白字符
  • [:punct:] 表示标点符号
  • [:upper:] 表示大写字符
  • [:lower:] 表示小写字符

查询所有以数字开头的记录:

select * from test where value regexp '^[:digit:]';

  • [:digit:] 代表所有数字,前面的^代表从开头开始匹配

查询所有以字母结尾的记录:

select * from test where value regexp '[:alpha:]$';

查询所有包含数字或字母的记录:

select * from test where value regexp '[:alnum:]';

查询所有包含空格的记录:

select * from test where value regexp '[:blank:]';

查询所有包含标点符号的记录:

select * from test where value regexp '[:punct:]';

查询包含大写字母的记录:

select * from test where value regexp '[:upper:]' COLLATE utf8mb4_0900_as_cs;

  • 这里多了一个子句COLLATE utf8mb4_0900_as_cs,指定排序规则区分大小写。MySQL8.0中字符集utf8mb4的默认排序规则是utf8mb4_0900_ai_ci,它是不区分大小写的(排序规则结尾的ci代表Case Insensitive 大小写不敏感,cs代表Case Sensitive 大小写敏感)。

如果不加这个排序规则子句,默认是不区分大小写的,纯小写字符记录也会被查询出来,与我们想查大写字符的意愿不同:

select * from test where value regexp '[:upper:]';

你也可以使用函数regexp_like函数中的参数来指定大小写是否敏感(这个函数是regexp的另一种写法):

select * from test where regexp_like(value, '[:upper:]', 'c')=1;

  • 前两个参数是expr和pattern,第三个参数可以指定大小写是否敏感:'c' 大小写敏感,'i' 大小写不敏感

2.5 修改匹配的数据

很多时候,我们查找出某类数据后,就是为了修改它,利用regexp_replace函数可以修改正则表达式的匹配结果。

语法:regexp_replace(expr, pattern, replacement [, pos[, occurrence[, match_type]]])

参数解释:

  • expr: 要搜索的内容
  • pattern: 匹配的模式
  • replacement: 替换的内容
  • pos: 起始搜索的位置,默认是1,即从头开始匹配
  • occurrence: 匹配发生的次数,默认是0,即替换所有匹配项
  • match_type: 匹配模式,和regexp_like相同,常用的是:'c' 大小写敏感,'i' 大小写不敏感

下面通过几个示例来理解,将字符串'ababab'中的a替换为x:

select regexp_replace('ababab','a','x');

将字符串'ababab'中的a替换为x,但是从第2位开始搜索:

select regexp_replace('ababab','a','x',2);

  • 这里使用了一个位置参数2,表示从第二位开始搜索,所以开头的a没有被替换

将字符串'ababab'中的a替换为x,但是从第2位开始搜索,并将第2次匹配的位置替换为x:

select regexp_replace('abababab','a','x',2,2);

  • 这里使用了位置参数2,和发生的次数2,即从第2位开始,只有第二个匹配的a会被替换为x

将test表中的首次匹配2大写字符替换为字符串'这里有两个大写字符':

select value, regexp_replace(value,'[:upper:]{2}','这里有两个大写字符',1,1,'c') after_replace from test where value regexp '[:upper:]' COLLATE utf8mb4_0900_as_cs;

  • 模式[:upper:]{2},代表任意大写字符重复2次
  • 后面的1,1分别代表从头开始搜索,只匹配第一次
  • 'c' 代表大小写敏感

修改前要先查询一下元数据和修改后的数据(最好备份一下),一是确认修改范围是不是我们想要匹配的数据,二是修改结果对不对,没有问题时再执行update:

update test set value=regexp_replace(value,'[:upper:]{2}','这里有两个大写字符',1,1,'c') where value regexp '[:upper:]' COLLATE utf8mb4_0900_as_cs;

select * from test;

可以看到,我们通过正则表达式匹配并更新成功了。

注意:在MySQL8.0.17版本前,这个函数返回的结果字符集是UTF-16(这是一个BUG),这可能导致你查询的结果和最后的更新结果不同,因此采用此函数批量匹配更新前一定要做好备份。

以上便是MySQL中常用的模糊匹配方法,可以满足大部分场景的模糊匹配。但是如果数据量非常大,例如需要在富文本中匹配想要的数据,上面的匹配方法有可能会比较慢,此时可以考虑采用使用另一种匹配技术:全文索引(Full-Text Index)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1191243.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SSM的社区生鲜电商平台

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

Java / Android 多线程和 synchroized 锁

s AsyncTask 在Android R中标注了废弃 synchronized 同步 Thread: thread.start() public synchronized void start() {/*** This method is not invoked for the main method thread or "system"* group threads created/set up by the VM. Any new functionali…

Visual Interpretability for Deep Learning: a Survey

Visual Interpretability for Deep Learning: a Survey----《深度学习的视觉可解释性:综述》 摘要 本文回顾了最近在理解神经网络表示以及学习具有可解释性/解耦的中间层表示的神经网络方面的研究。尽管深度神经网络在各种任务中表现出了优越的性能,但可解释性始终…

基于SpringBoot+Vue+uniapp微信小程序实验室预约管理平台详细设计和实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

getid3 获取视频时长

1、首先,我们需要先下载一份PHP类—getid3https://codeload.github.com/JamesHeinrich/getID3/zip/master 2.我在laravel6.0 中使用 需要在composer.json 自动加载 否则系统访问不到 在命令行 执行 composer dump-autoload $getID3 new \getID3();//视频文件需要放…

【PostgreSql本地备份为dump文件与恢复】使用脚本一键备份为dump文件

环境:windows数据库:postgresql 1.准备脚本 backUpDb.bat 脚本为备份脚本,双击运行,右键可以选择编辑;restoreDb.bat 脚本为恢复脚本,双击运行,右键选择编辑; 1.1 脚本介绍 如上图…

数据结构:串(定义,基本操作,存储结构)

目录 1.串的定义2.串的基本操作3.字符集编码4.串的存储结构1.顺序存储2.链式存储 1.串的定义 串,即字符串( String)是由零个或多个字符组成的有限序列。 一般记为s ‘a1a2……an’ (n ≥0) 其中,S是串名,单引号括起来的字符序列是…

企业清算有哪些类型?在哪里可以查看相关公告?

企业清算是什么? 企业清算指企业按章程规定解散以及由于破产或其他原因宣布终止经营后,对企业的财产、债权、债务进行全面清查,并进行收取债权,清偿债务和分配剩余财产的经济活动。 企业清算给分为破产清算,非破产清…

华为云交换数据空间 EDS:“可信、可控、可证”能力实现你的数据你做主

文章目录 前言一、数据安全流通价值的必要性和紧迫性1.1、交换数据空间(EDS)背景1.2、《数字中国建设整体布局规划》1.3、数据流通成为制约数据要素价值释放的瓶颈 二、华为云 EDS 解决方案介绍2.1、构建可控数据交换空间2.2、可控的数据交换框架2.3、定…

互联网医院|线上医疗引领行业发展

您是否曾经遇到过这样的问题:在忙碌的工作中,突然感到身体不适,但却又不想浪费时间和金钱去实体医院?或者是因为疫情的限制,出门看病变得困难重重?那么,今天我要向您介绍的,正是解决…

中断 NVIC的概念和原理

1.什么是中断 中断: 由于中断源的触发,常规程序被打断, CPU转 而运行中断响应函数,而后又回到常规程序的执行, 这一过程叫做中断。 中断优先级的概念 中断的意义和作用 中断处理的过程和术语 STM32 GPIO外部中断简…

【java:牛客每日三十题总结-3】

java:牛客每日三十题总结 总结如下 总结如下 集合相关知识点 Collection主要的子接口: List:可以存放重复内容 Set:不能存放重复内容,所有重复的内容靠hashCode()和equals()两个方法区分 Queue:队列接口 SortedSet:可以对集合中的数据进行排序 Map没有继承Collection接口&…

最新AI系统ChatGPT源码+AI绘画系统源码+支持GPT4.0+Midjourney绘画+搭建部署教程+附源码

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

黑豹程序员-SpringBoot中整合knife4j接口文档

1、Knife介绍 黑豹程序员-架构师学习路线图-百科&#xff1a;Knife4j API接口文档管理 2、坐标 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.7</version&…

银河麒麟等 Linux系统 安装 .net 3.1,net 6及更高版本的方法

确定 系统的版本。华为鲲鹏处理器是 Arm64位的。 于是到windows 官网下载对应版本 .net sdk 下载地址 https://dotnet.microsoft.com/zh-cn/download/dotnet 2.下载完成后&#xff0c;再linux 服务器 上进入到文件所在目录&#xff0c;建议全英文路径。 然后依次输入以下命令 …

图论09-桥和割点

文章目录 1 寻找桥的算法2 桥的代码实现3 寻找割点的算法4 割点的代码实现 1 寻找桥的算法 2 桥的代码实现 package Chapt06_Bridge;import java.util.ArrayList;public class FindBridges {private Graph G;private boolean[] visited;//ord数组记录访问的顺序private int or…

极狐GitLab CI 助力 .Net 项目研发效率和质量双提升

目录 .NET nuget 自动生成测试包&#xff08;prerelease&#xff09;版本号 .NET 版本号规范 持续集成自动打包 持续集成自动修改版本号 .NET 行级增量代码规范——拯救老项目 本地全量代码规范 行级增量代码规范 很多团队或开发者都会使用 C#、VB 等语言开发 .Net 应用…

区块链游戏,游戏开发

区块链游戏是一种基于区块链技术的新兴游戏类型&#xff0c;它具有去中心化、安全性高、透明度高、可追溯等特点。与传统的游戏开发相比&#xff0c;区块链游戏开发需要更多的技术和知识储备&#xff0c;同时也需要更加注重游戏本身的玩法和用户体验。 在区块链游戏中&#xff…

【PHP网页应用】MySQL数据库增删改查 基础版

使用PHP编写一个简单的网页&#xff0c;实现对MySQL数据库的增删改和展示操作 页面实现在index.php&#xff0c;其中basic.php为没有css美化的原始人版本 函数实现在database.php 目录 功能基本实现版 CSS美化版 basicindex.php index.php database.php 代码讲解 功能基…

红海云签约和兆服饰,科技引领服饰行业人力资源数字化转型

和兆服饰从事多品牌多品类经营管理&#xff0c;旗下拥有POLOSPORT、POLOKIDS、CARTELO等国际品牌。作为一个主打POLO文化的服饰品牌&#xff0c;诞生于美国的POLOSPORT拥有现代感的产品设计、系列化的产品搭配、全方位的服务&#xff0c;是最具美国马球精神的休闲时尚服饰品牌之…