常用正则表达式

一、正则表达式语法

1. 元字符

  • 字符匹配符
  • 选择匹配符
  • 限定符
  • 定位符
  • 分组组合和反向引用符

元字符(Metacjaracter)转义号\\

\\符号 说明:在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义符号,否则检索不到结果,甚至会报错。

特殊:在Java的正则表达式中,两个\\代表其他语言中的一个\

需要用到转义符号的字符有.*+()&/\?[]^{}

案例:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp01* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 17:40* @Version 1.0.0*/
public class RegExp01 {public static void main(String[] args) {String content = "a(.dd$.(%^(";//匹配所有字符//String regStr = ".";//匹配点//String regStr = "\\.";//匹配括号String regStr = "\\(";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()){System.out.println("找到" + matcher.group(0));}}
}

运行结果:

在这里插入图片描述

1.1. 字符匹配符
符号符号含义示例解释结果
[]可接收的字符列表[efgh]efgh中的任意1个字符eh
[^]不接收的字符列表[^abc]abc之外的任意1个字符dh
-连字符a-z任意单个小写字母ab
.匹配除\n以外的任意字符,如果只想匹配.则需要用\\.a..ba开头,b结尾,中间包括2个任意字符的长度为4的字符串addba#*b
\\d匹配单个数字字符,相当于[0-9]\\d{3}(\\d)?包含3个或4个数字的字符串123、7536
\\D匹配单个非数字字符,相当于[^0-9]\\D(\\d)*以单个非数字字符开头,后接任意个数字字符串aR75
\\w匹配单个数字、大小写字母字符、下划线,相当于[0-9、a-z、A-Z、_]\\d{3}\\w{4}以3个数字字符开头的长度为7的数字字母字符串456adFG753Tfhd
\\W匹配单个非数字、大小写字母字符,相当于[^0-9、a-z、A-Z、_]\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串+代表1个或多个#52$%^52
\\s匹配空白字符
\\S匹配非空白字符

案例:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp02* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 17:45* @Version 1.0.0*/
public class RegExp02 {public static void main(String[] args) {String content = "ad44w8\n5.B6b5d";//小写a-z
//        String regStr = "[a-z]";//大写A-Z
//        String regStr = "[A-Z]";//[^a-z]{2} 不在a-z之间的连续两个字符
//        String regStr = "[^a-z]{2}";//全部都匹配String regStr = ".";//方法一:(?i)不区分大小写
//        String regStr = "(?i)wb";Pattern pattern = Pattern.compile(regStr);//方法二:这种方法也可以不区分大小写
//        Pattern pattern = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到:" + matcher.group(0));}}
}

[^a-z]{2} 不在a-z之间的连续两个字符结果:

在这里插入图片描述

1.2. 选择匹配符

在匹配某个字符串的时候是选择性的。即:既可以匹配这个,又可以匹配那个,这时需要用到选择匹配符号|

符号符号含义示例解释
``匹配``之前或之后的表达式

案例:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp03* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 17:49* @Version 1.0.0*/
public class RegExp03 {public static void main(String[] args) {String content = "盖被子 dd 暖和阿斯顿aa想睡";String regStr = "被子|暖和|睡";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到:" + matcher.group(0));}}
}

运行结果:

在这里插入图片描述

1.3. 限定符

用于指定其前面的字符和组合项连续出现多少次

符号符号含义示例解释结果
*指定符号重复0次或n次(无要求)(abc)*仅包含任意abc的字符串abcabcabc
+指定字符重复1次或n次(至少一次)m+(abc)*以至少1个m开头,后接任意个abc的字符串mmabcmabcabcmmabc
?指定字符重复0次或1次(最多1次)m+abc?以至少1个m开头,后接ababc的字符串,?接最近的mabmabcmmab
{n}只能输入n个字符[abc]abc中字母组成的任意长度为3的字符串abcdbcadc
{n,}指定至少n个匹配[abcd]abcd中字母组成的任意长度不小于3的字符串abcddddd
{n,m}指定至少n个但不多于m个匹配[abcd]abcd中字母组成的任意长度不小于3,并且不大于5的字符串abcabcdaaaaa

案例:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp04* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 17:53* @Version 1.0.0*/
public class RegExp04 {public static void main(String[] args) {String content = "asdmmabffm111111amabmabc";
//        String regStr = "m+abc?";//Java默认贪婪匹配,尽可能匹配多的String regStr = "1{4,5}";//结果只有5个1Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到:" + matcher.group(0));}}
}

运行结果:

在这里插入图片描述

1.4. 定位符

规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置

符号符号含义示例解释结果
^指定起始字符^[0-9]+[a-z]*以至少1个数字开头,后接任意个小写字母的字符串2、56f
$指定结束字符^[0-9]\\-[a-z]+$以1个数字开头后接连字符-,并以至少1个小写字母结尾的字符串1-a2-dd
\\b匹配目标字符串的边界qy\\b这里的边界是指离空格最近的和离结束位置最近的qydsjdqy qyfffqy
\\B匹配目标字符串的非边界qy\\b\\b相反,指开头第一次出现qydsjdqy qyfffqy

案例:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp05* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 17:56* @Version 1.0.0*/
public class RegExp05 {public static void main(String[] args) {String content = "asdmmabffm111111a1";//定位符只能找到一个返回String regStr = "^[a-z]+[0-9]";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到:" + matcher.group(0));}}
}

运行结果:

在这里插入图片描述

1.5. 分组
1.5.1. 常用分组
常用分组构造形式解释
(pattern)非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其它捕获结果则根据左括号的顺序从1开始自动编号。
(?<name>patter)命名捕获。将匹配的子字符串捕获到一个组名称或编号名称中。用于name的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如(?'name')但是我尝试不能使用

非命名分组:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp06* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 17:58* @Version 1.0.0*/
public class RegExp06 {public static void main(String[] args) {String content = "dcxuexi dda5524 dadaqy";String regStr = "(\\d\\d)(\\d\\d)";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到=" + matcher.group(0));//5524System.out.println("找到=" + matcher.group(1));//55System.out.println("找到=" + matcher.group(2));//24}}
}

运行结果:

在这里插入图片描述

命名分组:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp06* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 17:58* @Version 1.0.0*/
public class RegExp06 {public static void main(String[] args) {String content = "dcxuexi dda5524 dadaqy";String regStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到=" + matcher.group(0));//5524System.out.println("找到=" + matcher.group("g1"));//55System.out.println("找到=" + matcher.group("g2"));//24}}
}

运行结果:

在这里插入图片描述

1.5.2. 特别分组
特别分组构造形式解释
(?:patter)匹配pattern但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用or字符
(?=pattern)它是一个非捕获匹配。例如,Windows (?=95
(?!pattern)该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配。例如,Windows (?!95

案例:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp07* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:03* @Version 1.0.0*/
public class RegExp07 {public static void main(String[] args) {//说明非捕获的不能用group(1)去获取String content = "hh阿典yyds 66阿典nb 99阿典xnlxixi";//第一部分(?:patter)
//        String regStr = "阿典yyds|阿典nb|阿典xnl";//等价于非捕获分组
//        String regStr = "阿典(?:yyds|nb|xnl)";//第二部分(?=pattern)//只找到阿典yyds与阿典nb中的阿典
//        String regStr = "阿典(?=yyds|nb)";//第三部分(?!=pattern)//只找到不是阿典yyds与阿典nb中的阿典String regStr = "阿典(?!yyds|nb)";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到:" + matcher.group(0));}}
}

运行结果:

在这里插入图片描述

2. 非贪婪匹配

Java正则表达式默认的是贪婪匹配,如果想要进行非贪婪匹配就在需要的地方加一个?

案例:

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp08* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:05* @Version 1.0.0*/
public class RegExp08 {public static void main(String[] args) {String content = "456m";
//        String regStr = "\\d+";//贪婪匹配 456String regStr = "\\d+?";//非贪婪匹配 一个一个输出Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()){System.out.println("找到" + matcher.group(0));}}
}

运行结果:

在这里插入图片描述

二、正则表达式三个常用类

java.util.regex包主要包括以下三个类Pattern类、Matcher类和PatternSyntaxException

1. Pattern

pattern对象是一个正则表达式对象。Pattern类没有公共构造方法。要创建一个Pattern对象,调用其公共静态方法,它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数,比如:Patternr=Pattern.compile(pattern);

package com.dcxuexi.regexp;import java.util.regex.Pattern;/**** @Title RegExp10* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:09* @Version 1.0.0*/
public class RegExp10 {public static void main(String[] args) {String content = "https://blog.csdn.net/qq_37726813?type=blog";//这里去掉了左右的定位符String regStr = "((http|https)://)([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.]*)?";System.out.println(Pattern.matches(regStr,content));}
}

运行结果:

在这里插入图片描述

2. Matcher

Matcher对象是对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的matcher方法来获得一个Matcher对象

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp11* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:13* @Version 1.0.0*/
public class RegExp11 {public static void main(String[] args) {String content = "hello ddd hello dsa$ hello";String regStr = "hello.*";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("================");System.out.println(matcher.start());System.out.println(matcher.end());System.out.println("找到:" + content.substring(matcher.start(),matcher.end()));System.out.println("整体匹配:"+matcher.matches());}//matcher.replaceAll()用于替换regStr = "hello";pattern = Pattern.compile(regStr);matcher = pattern.matcher(content);//原来的文本并不会替换/*** 结果* 你好 ddd 你好 dsa$ 你好* hello ddd hello dsa$ hello*/String newContent = matcher.replaceAll("你好");System.out.println(newContent);System.out.println(content);}
}

运行结果:

在这里插入图片描述

3. PatternSyntaxException

PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

三、分组、捕获、反向引用

1. 分组

我们可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分我们可以看作是一个子表达式/一个分组。

2. 捕获

把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。组0代表的是整个正则式

3. 反向引用

圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用\\分组号,外部反向引用$分组号

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp12* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:19* @Version 1.0.0*/
public class RegExp12 {public static void main(String[] args) {String content = "hel522511lo d1234111dd h55ell3o dsa$ hello";//匹配连续相同的两个数字//String regStr = "(\\d)\\1";//String regStr = "(\\d)\\1{1}";//String regStr = "(\\d)(\\d)";//匹配连续三个相同的字符//String regStr = "(\\d)\\1{2}";//匹配个位与千位相同十位与百位相同的字符 如:1221String regStr = "(\\d)(\\d)\\2\\1";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while(matcher.find()){System.out.println("找到:"+matcher.group(0));}}
}

运行结果:

在这里插入图片描述

反向引用就是通过分组的组名去再次利用分组

四、正则表达式应用

1. 简单应用

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp13* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:22* @Version 1.0.0*/
public class RegExp13 {public static void main(String[] args) {//QQ号   1-9开头的String content = "10006";String regStr = "^[1-9][0-9]{4,10}$";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);if(matcher.find()){System.out.println("满足格式");}else{System.out.println("不满足格式");}}
}

运行结果:

在这里插入图片描述

2. 判断url

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp14* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:25* @Version 1.0.0*/
public class RegExp14 {public static void main(String[] args) {String content = "https://blog.csdn.net/qq_37726813?type=blog";/**** 1.先用((http|https)://)确定url的开始部分 http:// | https://* 2.再用([\w-]+\.)+[\w-]+确定blog.csdn.net* 3.再用[\w-]+(\/[\w-?=&/%.]*)?确定/qq_37726813?type=blog* 说明[]里面的东西都会是原样的*/String regStr = "^((http|https)://)([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.]*)?$";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);if(matcher.find()){System.out.println("满足格式");}else{System.out.println("不满足格式");}}
}

运行结果:

在这里插入图片描述

3. 结巴去重

package com.dcxuexi.regexp;import java.util.regex.Matcher;
import java.util.regex.Pattern;/**** @Title RegExp15* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:28* @Version 1.0.0*/
public class RegExp15 {public static void main(String[] args) {String content = "我....我要....学学学学...编程java!";//1.去掉所有.(我我要学学学学编程java!)Pattern pattern = Pattern.compile("\\.");Matcher matcher = pattern.matcher(content);content = matcher.replaceAll("");System.out.println(content);//2.去掉重复的字//使用反向引用$1来替换匹配到的内容content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");System.out.println(content);}
}

运行结果:

在这里插入图片描述

说明:

为什么一个$1就可以替换不同的字符呢,为什么不只是替换第一个字符,可能你有这样的疑问,

解释:这还要看源码,通过源码我们可以得知分组的位置不是递增的而是一次一次被替换的,因此他始终会在1分组,开始在1分组中,然后用替换了全部连续的,之后要替换进入第一个分组,重复上述操作等等

4. 分割字符串

package com.dcxuexi.regexp;/**** @Title RegExp16* @Description TOTD* @Auter DongChuang* @Date 2023/12/30 18:30* @Version 1.0.0*/
public class RegExp16 {public static void main(String[] args) {String content = "dc#dha-jd=你好=aj?d51~ddd";String[] split = content.split("#|-|~|\\d+|=|\\?");for (String i :split){System.out.println(i);}}
}

运行结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows上ModbusTCP模拟Master与Slave工具的使用

场景 Modbus Slave 与 Modbus Poll主从设备模拟软件与Configure Virtual Serial串口模拟软件使用&#xff1a; Modebus Slave 与 Modbus Poll主从设备模拟软件与Configure Virtual Serial串口模拟软件使用_modbus poll激活-CSDN博客 数据对接协议为Modbus TCP,本地开发需要使…

基于ElementUI二次封装弹窗组件

效果&#xff1a; 一、自定义内容类型弹窗 <!-- title&#xff1a;对话框的标题confirmLoading&#xff1a;当前是否处于提交中titleCenter&#xff1a;对话框标题居中方式footerCenter&#xff1a;底部按钮的对其方式visible&#xff1a;是否显示弹窗width&#xff1a;设置…

自动化测试系列 之 Python单元测试框架unittest

一、概述 什么是单元测试 单元测试是一种软件测试方法&#xff0c;是测试最小的可测试单元&#xff0c;通常是一个函数或一个方法。 在软件开发过程中&#xff0c;单元测试作为一项重要的测试方法被广泛应用。 为什么需要单元测试 单元测试是软件开发中重要的一环&#xf…

前后端分离架构的特点以及优缺点

文章目录 一、前后端不分离架构(传统单体结构)1.1 什么是前后端不分离1.2 工作原理1.3 前后端不分离的优缺点1.4 应用场景 二、前后端分离架构2.1 为什么要前后端分离2.2 什么是前后端分离2.3 工作原理2.4 前后端分离的优缺点 参考资料 一、前后端不分离架构(传统单体结构) 首…

LAMP集中式搭建+LNMP分布式搭建(新版)

LAMP搭建LNMP搭建 LAMP搭建LNMP搭建一、LAMP搭建(集中式)1、LAMP简介2、LAMP组件及作用3、编译安装Apache httpd服务4、编译安装mysqld 服务5、编译安装PHP解析环境6、安装论坛7、安装博客 二、LNMP搭建(分布式)1、LNMP工作原理2、安装nginx3、安装mysql4、安装php5、在浏览器测…

Unity坦克大战开发全流程——开始场景——设置界面

开始场景——设置界面 step1&#xff1a;设置面板的背景图 照着这个来设置就行了 step2&#xff1a;写代码 关联的按钮控件 监听事件函数 注意&#xff1a;要在start函数中再写一行HideMe函数&#xff0c;以便该面板能在一开始就能隐藏自己。 再在BeginPanel脚本中调用该函数即…

1.S32K3电源和复位

一、电源 S32K3系列芯片的电源各不相同。以S32K34x&#xff0c;S32K32x及S32K314为例。 并且该芯片支持以下特性&#xff1a; • Combination of internal and external voltage regulator options, offering RUN and Standby modes • FPM , which is used on chip-level in…

市场复盘总结 20231229

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整 昨日回顾: -- 今日 SELECT * FROM (SELECT TOP 100 CODE,20231229 入选日期,成交额排名,净流入排名,代码,名称,DDE大单金额,涨幅,主力净额,DDE大单净量,CONVERT(DATETIM…

Linux驱动开发简易流程

推荐视频&#xff1a; 正点原子【第四期】手把手教你学 Linux之驱动开发篇 小智-学长嵌入式Linux&Android底层开发入门教程 能力矩阵 基础能力矩阵 熟悉c/c、熟悉数据结构 熟悉linux系统&#xff0c;Shell脚本&#xff0c;Makefile/cmake/mk 文件IO、多线程、竞争、并发…

Python实现员工管理系统(Django页面版 ) 七

各位小伙伴们好久不见&#xff0c;2024年即将到来&#xff0c;小编在这里提前祝大家新的一年快快乐乐&#xff0c;能够事业有成&#xff0c;学习顺心&#xff0c;家庭和睦&#xff0c;事事顺利。 今天我们本篇要实现的是一个登录界面的实现&#xff0c;其实登录界面的实现看着挺…

【linux】Linux管道的原理与使用场景

Linux管道是Linux命令行界面中一种强大的工具&#xff0c;它允许用户将多个命令链接起来&#xff0c;使得一个命令的输出可以作为另一个命令的输入。这种机制使得我们可以创建复杂的命令链&#xff0c;并在处理数据时提供了极大的灵活性。在本文中&#xff0c;我们将详细介绍Li…

nacos入门篇001-安装与启动

1、下载zip包 我这里下载的是版本2.2.0 Nacos 快速开始 2、修改配置文件 2.1集群模式修改成单例模式 vi startup.sh 2.2 修改数据库配置信息 3、初始化数据库 3.1 创建db名称&#xff1a;db_nacos 3.2 执行mysql-schema.sql 3.3 执行完截图&#xff1a; 4、运行脚本启动 …