当前位置: 首页 > news >正文

正则表达式完全指南,总结全面通俗易懂

目录

元字符

连接符

限定符

定位符

修饰符(标记)

运算符优先级

普通字符集及其替换

零宽断言

正向先行断言

负向先行断言

正向后发断言

负向后发断言

捕获组

普通捕获组

命名捕获组

PS:非捕获组



正则表达式在线测试:  正则在线测试工具

元字符

字符描述
\d

匹配一个数字字符。等价于 [0-9]。

\D

匹配一个非数字字符。等价于 [^0-9]。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。

\S

匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

\w

匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。

\W

匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。

\n

匹配一个换行符。等价于 \x0a 和 \cJ。

\r

匹配一个回车符。等价于 \x0d 和 \cM。

\t

匹配一个制表符。等价于 \x09 和 \cI。

\f

匹配一个换页符。等价于 \x0c 和 \cL。

\

将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。

.

匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像"(.|\n)"的模式。

[ ]

字符种类。匹配方括号内的任意字符。

[^ ]

否定的字符种类。匹配除了方括号里的任意字符

连接符

字符描述
[0-9]匹配数字,等价于\d
[a-z]匹配英文小写字母
[A-Z]

匹配英文大写字母

[0-9a-zA-z]匹配数字或英文字母
[\u4e00-\u9fa5]匹配一个汉字

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。

正则表达式的限定符有:

字符描述
*匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于 {0,}。
+匹配前面的子表达式一次或多次。例如,zo+ 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
?

匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 "do""does""doxy" 中的 "do""does"。? 等价于 {0,1}。

{n}n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 "Bob" 中的 o,但是能匹配 "food" 中的两个 o
{n,}n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 "Bob" 中的 o,但能匹配 "foooood" 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。
{n,m}m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 "fooooood" 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。

定位符

定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

正则表达式的定位符有:

字符描述
^匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。
$匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。
\b匹配一个单词边界,即字与空格间的位置。
\B非单词边界匹配。

注意:不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。

若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。

修饰符(标记)

标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。

标记不写在正则表达式里,标记位于表达式之外,格式如下:

修饰符含义描述
iignore - 不区分大小写将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。
gglobal - 全局匹配查找所有的匹配项。
mmulti line - 多行匹配使边界字符 ^ 和 $ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。
s特殊字符圆点 . 中包含换行符 \n默认情况下的圆点 . 是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。

运算符优先级

正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。

相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:

运算符描述
\转义符
(), (?:), (?=), []圆括号和方括号
*, +, ?, {n}, {n,}, {n,m}限定符
^, $, \任何元字符、任何字符定位点和序列(即:位置和顺序)
|替换,"或"操作
字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。

普通字符集及其替换

符号替换正则描述
\d[0-9]匹配数字字符
\D[^0-9]匹配非数字字符
\w0-9a-zA-z]匹配数字或字母或下划线
\W[^\w]匹配非数字或字母或下划线
\s[\r\t\n\f]匹配任意的空白符,如空格,换行符,制表符等
\S[^\s]匹配任意不是空白符的字符

零宽断言

  • 所谓断言,是用来声明一个应该为真的事实。在正则表达式中,只有当断言为真时才会继续进行匹配。
  • 零宽断言:像用于查找某些内容之前或者之后的东西,其中一些特殊字符如“\b、^、$”等用于指定一个位置,这个位置应满足一定的条件。

正向先行断言

(?=pattern) 匹配 pattern 之前的位置,即:要想满足匹配,后面得跟着 pattern

负向先行断言

(?!pattern) 匹配 pattern 之前的位置,即:要想满足匹配,后面不能跟着 pattern

正向后发断言

(?<=pattern) 匹配 pattern 之后的位置,即:要想满足匹配,前面得跟着 pattern

负向后发断言

(?<!pattern) 匹配 pattern 之后的位置,即:要想满足匹配,前面不能跟着 pattern

规律 所谓”正”,即字符中需要出现 pattern ;所谓“负”,即字符中不能出现 pattern ; 所谓“先”,即匹配在 pattern 前的位置 ; 所谓“后”,即匹配在 pattern 后的位置;

捕获组

捕获组分为:

  • 普通捕获组(Expression)
  • 命名捕获组(?Expression)

普通捕获组

从正则表达式左侧开始,每出现一个左括号"("记做一个分组,分组编号从 1 开始。0 代表整个表达式。

对于时间字符串:2017-04-25,表达式如下

(\\d{4})-((\\d{2})-(\\d{2}))

有 4 个左括号,所以有 4 个分组:

编号捕获组匹配
0(\d{4})-((\d{2})-(\d{2}))2017-04-25
1(\d{4})2017
2((\d{2})-(\d{2}))04-25
3(\d{2})04
4(\d{2})25
public static final String DATE_STRING = "2017-04-25";
public static final String P_COMM = "(\\d{4})-((\\d{2})-(\\d{2}))";Pattern pattern = Pattern.compile(P_COMM);
Matcher matcher = pattern.matcher(DATE_STRING);
matcher.find();//必须要有这句System.out.printf("\nmatcher.group(0) value:%s", matcher.group(0)); 
System.out.printf("\nmatcher.group(1) value:%s", matcher.group(1)); 
System.out.printf("\nmatcher.group(2) value:%s", matcher.group(2)); 
System.out.printf("\nmatcher.group(3) value:%s", matcher.group(3)); 
System.out.printf("\nmatcher.group(4) value:%s", matcher.group(4));

命名捕获组

每个以左括号开始的捕获组,都紧跟着 ?,而后才是正则表达式。

对于时间字符串:2017-04-25,表达式如下:

(?<year>\\d{4})-(?<md>(?<month>\\d{2})-(?<date>\\d{2}))

有 4 个命名的捕获组,分别是:

编号名称捕获组匹配
00(?\d{4})-(?(?\d{2})-(?\d{2}))2017-04-25
1year(?\d{4})-2017
2md(?(?\d{2})-(?\d{2}))04-25
3month(?\d{2})04
4date(?\d{2})25

命名的捕获组同样也可以使用编号获取相应值。

public static final String P_NAMED = "(?<year>\\d{4})-(?<md>(?<month>\\d{2})-(?<date>\\d{2}))";
public static final String DATE_STRING = "2017-04-25"; 
Pattern pattern = Pattern.compile(P_NAMED);
Matcher matcher = pattern.matcher(DATE_STRING);
matcher.find();System.out.printf("\n===========使用名称获取============="); 
System.out.printf("\nmatcher.group(0) value:%s", matcher.group(0)); 
System.out.printf("\n matcher.group('year') value:%s", matcher.group("year")); 
System.out.printf("\nmatcher.group('md') value:%s", matcher.group("md")); 
System.out.printf("\nmatcher.group('month') value:%s", matcher.group("month")); 
System.out.printf("\nmatcher.group('date') value:%s", matcher.group("date"));matcher.reset();System.out.printf("\n===========使用编号获取=============");
matcher.find(); 
System.out.printf("\nmatcher.group(0) value:%s", matcher.group(0)); 
System.out.printf("\nmatcher.group(1) value:%s", matcher.group(1)); 
System.out.printf("\nmatcher.group(2) value:%s", matcher.group(2)); 
System.out.printf("\nmatcher.group(3) value:%s", matcher.group(3)); 
System.out.printf("\nmatcher.group(4) value:%s", matcher.group(4));

PS:非捕获组

在左括号后紧跟 ?:,而后再加上正则表达式,构成非捕获组 (?:Expression)。

对于时间字符串:2017-04-25,表达式如下:

(?:\\d{4})-((\\d{2})-(\\d{2}))

这个正则表达式虽然有四个左括号,理论上有 4 个捕获组。但是第一组 (?:\d{4}),其实是被忽略的。当使用 matcher.group(4) 时,系统会报错。

编号捕获组匹配
0(\d{4})-((\d{2})-(\d{2}))2017-04-25
1((\d{2})-(\d{2}))04-25
2(\d{2})04
3(\d{2})25
public static final String P_UNCAP = "(?:\\d{4})-((\\d{2})-(\\d{2}))";
public static final String DATE_STRING = "2017-04-25";Pattern pattern = Pattern.compile(P_UNCAP);
Matcher matcher = pattern.matcher(DATE_STRING);
matcher.find();System.out.printf("\nmatcher.group(0) value:%s", matcher.group(0)); 
System.out.printf("\nmatcher.group(1) value:%s", matcher.group(1)); 
System.out.printf("\nmatcher.group(2) value:%s", matcher.group(2)); 
System.out.printf("\nmatcher.group(3) value:%s", matcher.group(3));// Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 4 
System.out.printf("\nmatcher.group(4) value:%s", matcher.group(4));

总结

  • 普通捕获组使用方便;
  • 命名捕获组使用清晰;
  • 非捕获组目前在项目中还没有用武之地。

相关文章:

正则表达式完全指南,总结全面通俗易懂

目录 元字符 连接符 限定符 定位符 修饰符&#xff08;标记&#xff09; 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 捕获组 普通捕获组 命名捕获组 PS:非捕获组 正则表达式在线测试: 正则在线测试工具 …...

运维面试题.云计算面试题之三ELK

1.ELK是什么? ELK 其实并不是一款软件,而是一整套解决方案,是三个软件产品的首字母缩写 Elasticsearch:负责日志检索和储存 Logstash:负责日志的收集和分析、处理 Kibana:负责日志的可视化 这三款软件都是开源软件,通常是配合使用,而且又先后归于 Elastic.co 公司名下,…...

C# DataTable使用Linq查询详解

前奏- C# 对DataTable进行查询 C# 可以对 DataTable 进行查询。在 .NET 框架中&#xff0c;DataTable 类提供了几种方法来查询数据&#xff0c;包括 Select 方法和 AsEnumerable 扩展方法&#xff08;在 System.Data.DataSetExtensions 命名空间中&#xff09;。 使用 Select…...

【企业级分布式系统】ELK优化

文章目录 Elasticsearch作为日志存储时的优化优化ES索引设置优化线程池配置锁定内存&#xff0c;不让JVM使用Swap减少分片数、副本数 Elasticsearch作为日志存储时的优化 linux内核优化、JVM优化、ES配置优化、架构优化&#xff08;filebeat/fluentd代替logstash、加入kafka做…...

51单片机基础05 定时器

目录 一、为什么要定时器 二、定时器中断 1、定时器中断参数 2、定时器中断程序 3、定时器计数 一、为什么要定时器 前文提到&#xff0c;比如进行流水灯等操作&#xff0c;都是直接写了delay_ms这类操作。 但是在51单片机中&#xff0c;其一般就是靠双for进行的循环时延&…...

tdengine学习笔记实战-jdbc连接tdengine数据库

先上代码&#xff0c;里面有两种获取连接的方式&#xff0c;一个单例&#xff0c;一个连接池 package com.tdengine.utils;import com.alibaba.druid.pool.DruidDataSource;import java.sql.*; import java.util.Properties;public class TDConnectUtils {// 单例对象private …...

vue3项目执行npm install下载依赖报错问题排查方法

1、检查当前node与npm的版本 nodejs 和 npm 的版本是有适配的&#xff0c;具体可以看官网&#xff1a;nodejs 和 npm 的版本是有适配的 若是版本不兼容&#xff0c;修改node或者npm的版本即可&#xff0c;建议使用nvm版本管理工具&#xff0c;切换方便&#xff1b; 2、清除缓…...

【vue】项目迭代部署后 自动清除浏览器缓存

前言&#xff1a; vue项目打包部署上线后&#xff0c;因浏览器缓存问题&#xff0c;导致用户访问的依旧是上个迭代批次的旧资源&#xff0c;需要用户手动清除缓存才能更新至最新版本&#xff0c;影响用户体验。 解决方法&#xff1a; html根文件添加以下标签 <meta http-eq…...

Leetcode(滑动窗口习题思路总结,持续更新。。。)

讲解题目&#xff1a;长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target &#xff0c;找出该数组中满足其和 ≥ target 的长度最小的连续子数组。如果不存在符合条件的连续子数组&#xff0c;返回 0。示例: 输入: target 7, nums [2,3,1,2,4,3] 输出: 2 解…...

【UNIAPP】uniapp版图片压缩工具

二次封装的uniapp版本图片压缩、上传工具&#xff0c;支持全端&#xff08;H5、小程序、APP&#xff09; 新建文件&#xff1a;file-util.js class FileUtil {/*** [文件上传]* param {[object]} fileObj [图片地址]* param {[object]} formData [参数]* param {[str…...

PaddlePaddle 开源产业级文档印章识别PaddleX-Pipeline “seal_recognition”模型 开箱即用篇(一)

AI时代到来&#xff0c;各行各业都在追求细分领域垂直类深度学习模型&#xff0c;今天给大家介绍一个PaddlePaddle旗下&#xff0c;基于PaddleX Pipeline 来完成印章识别的模型“seal_recognition”。 官方地址&#xff1a;https://github.com/PaddlePaddle/PaddleX/blob/relea…...

Vue3 + Vite 项目引入 Typescript

文章目录 一、TypeScript简介二、TypeScript 开发环境搭建三、编译方式1. 自动编译单个文件2. 自动编译整个项目 四、配置文件1. compilerOptions基本选项严格模式相关选项&#xff08;启用 strict 后自动包含这些&#xff09;模块与导入相关选项 2. include 和 excludeinclude…...

微信小程序实战篇-分类页面制作

一、项目背景与目标 在微信小程序开发中&#xff0c;分类页面是一个常见且重要的功能模块。它能够帮助用户快速定位和浏览不同类别的商品或信息&#xff0c;提升用户体验和操作效率。今天&#xff0c;我们将深入探讨如何制作一个实用的微信小程序分类页面&#xff0c;先来看一下…...

第三十七章 如何清理docker 日志

如何清理docker 日志 目标 掌握docker 日志设置掌握docker日志的清理办法背景 在现代软件开发和部署环境中,Docker 容器技术因其轻量级、可移植性和高效资源利用的特点,已成为许多企业和开发团队的首选。Docker 容器在运行过程中会产生大量的日志信息,这些日志对于监控容器…...

二刷代码随想录第七天

454. 四数相加 II 先用map记录前两个数的和num1 num2的值出现了多少次再在后两个数组里找0 - (num1 num2),找到后就累加map中的次数 class Solution { public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3…...

1.tree of thought (使用LangChain解决4x4数独问题)

本教程将介绍如何使用LangChain库和chatglm API来解决一个4x4的数独问题。我们将通过以下步骤实现这一目标&#xff1a; 初始化chatglm 的聊天模型。定义数独问题和解决方案。创建一个自定义的检查器来验证每一步的思考。使用ToTChain来运行整个思考过程。 1. 初始化chatglm4…...

网络基础(4)IP协议

经过之前的学习对传输协议的学习&#xff0c;对于传输协议从系统底层到应用层对于socket套接字的学习已经有了一套完整的理论。 对于网络的层状结构&#xff0c;现在已经学习到了应用层和传输层: 在之前的学习中&#xff0c;通信的双方都只考虑了双方的传输层的东西&#xff0…...

124. 二叉树中的最大路径和【 力扣(LeetCode) 】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 124. 二叉树中的最大路径和 一、题目描述 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径…...

echarts:简单实现默认显示两柱子折线,点击按钮后显示新的柱子

问&#xff1a; 用echarts实现&#xff1a;默认显示两柱子折线&#xff0c;点击“税率”按钮&#xff0c;显示税率柱子&#xff0c;之前的两柱子折线消失 回答&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8…...

视频里的音频怎么提取出来成单独文件?音频提取照着这些方法做

在数字时代&#xff0c;视频与音频的分离与重组已成为日常需求之一。无论是出于制作背景音乐、保存讲座内容&#xff0c;还是编辑播客素材&#xff0c;提取视频中的音频并将其保存为单独文件都显得尤为重要。视频里的音频怎么提取出来成单独文件&#xff1f;本文将详细介绍几种…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...