Java正则表达式Pattern和Matcher

2023-11-04

Java字符串支持使用正则表达式进行替换和分隔操作,字符串提供的正则表达式操作是有限的,比如打印正则表达式匹配到的每一个字符串就无法通过字符串提供的方法来实现。Java使用Pattern和Matcher两个类来支持正则表达式功能,字符串提供的正则表达式功能实际也是调用这两个类来实现的。 本文将介绍Pattern和Matcher的使用方法。

Pattern

Pattern用来表示一个编译后的正则表达式,Pattern对象通过compile静态方法创建:

Pattern p = Pattern.compile("cat");

compile方法的参数即为正则表达式,上例中的正则表达式为cat。

Matcher

Matcher对象封装了匹配、替换、遍历等操作。它是通过Pattern对象的matcher方法创建:

Matcher m = p.matcher("one cat two cats in the yard");

matcher方法的参数为输入字符串或待匹配的字符串。

正则表达式功能为什么要用两个对象来实现?

Java把正则表达式功能划分为Pattern和Matcher,这样做的缺点是使用上稍显复杂,优点是多个Matcher可以共享同一个Pattern。Pattern表示编译后的正则表达式,多个Matcher共用一个Pattern时,正则表达式只需编译一次即可,提升了应用程序的性能,下面是多个Matcher对象共用一个Pattern示例:

Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat two cats in the yard");
Matcher m2 = p.matcher("i like my cat");
Matcher m3 = p.matcher("one dog one cat");

匹配

Matcher有三个方法可以进行匹配操作:

  • matches
  • lookingAt
  • find

matches方法使用正则表达式来匹配整个字符串,如果匹配返回true,否则返回false,下面是matches使用示例:

//正则表达式"cat"不能匹配整个字符串"i like my cat"
Pattern p = Pattern.compile("cat");
Matcher m1 = p.matcher("i like my cat");
if (m1.matches())
    System.out.println("matches");
else
    System.out.println("not matches");
/*程序输出
not matches
*/

//正则表达式"i like my cat"匹配整个字符串"i like my cat"
Pattern p = Pattern.compile("i like my cat");
Matcher m1 = p.matcher("i like my cat");
if (m1.matches())
    System.out.println("matches");
else
    System.out.println("not matches");
/*程序输出
matches
*/

lookingAt方法使用正则表达式来匹配字符串的开头部分,匹配返回true,不匹配则返回false。它和matches不同之处在于,lookingAt不是必须匹配整个字符串。下面是lookingAt使用示例:

//正则表达式"cat"无法匹配字符串"i like my cat"的开头
Pattern p = Pattern.compile("cat");
Matcher m1 = p.matcher("i like my cat");
if (m1.lookingAt())
    System.out.println("matches");
else
    System.out.println("not matches");
/*程序输出
not matches
*/

//正则表达式"i"匹配字符串"i like my cat"的开头
Pattern p = Pattern.compile("i");
Matcher m1 = p.matcher("i like my cat");
if (m1.lookingAt())
    System.out.println("matches");
else
    System.out.println("not matches");
/*程序输出
matches
*/

find方法可以使用正则表达式查找下一个匹配的字符串子串,如果查到匹配的字符串返回true否则返回false。查找到匹配的子串后可以通过start和end()两个方法来获取子串的起始和结束索引。find可以循环调用继续查找下一个匹配的子串,下面是find使用示例:

//使用正则表达式"i"匹配"i like my cat"
Pattern p = Pattern.compile("i");
Matcher m1 = p.matcher("i like my cat");
while (m1.find())
{
    System.out.printf("find [%d, %d]\n", m1.start(), m1.end());
}
/*程序输出
find [0, 1]
find [3, 4]
*/

组(Group)

组是正则表达式的一个子集,每个组都有一个编号,通过从左到右计算左括号来进行编号。正则表达式“((A)(B(C))) ”有4个组:

  1. ((A)(B(C)))
  2. (A)
  3. (B(C))
  4. (C)

组0表示整个正则表达式,除组0外每一个组都被一对括号括住,如果一个正则表达式里面没有括号,则它只有组0即整个表达式。下面是组号的示例程序:

Pattern p = Pattern.compile("([0-9]+)([^0-9]+)");
Matcher m1 = p.matcher("name jack, age 18, weight 70, height 178cm");
if (m1.find())
{
    System.out.printf("group0: %s\n", m1.group());
    System.out.printf("group1: %s\n", m1.group(1));
    System.out.printf("group2: %s\n", m1.group(2));
}
/*程序输出
group0: 18, weight 
group1: 18
group2: , weight 
*/

上例中组0是整个正则表达式"([0-9]+)([^0-9]+)",组1是第一个左括号括住的内容"([0-9]+)"表示一个数字,组2是第二个左括号括住的内容"([^0-9]+)"表示一个非数字。组0即整个正则表达式匹配到的内容为"18, weight",组1为"18",组2为", weight"。上例中我们只调用find方法一次,所以它只匹配一次。

遍历

使用Matcher对象的find方法查找到字符串时可以通过start和end两个方法获取到匹配字符串的的起止索引,通过起止索引可以获取到匹配到的字符串。还可以通过组号来获取匹配到的字符串,通过组号获取匹配的字符串更加灵活方便,group()方法获取组0,group(int)方法可以指定要获取的组号,示例如下:

//查找所有数字
Pattern p = Pattern.compile("[0-9]+");
Matcher m1 = p.matcher("name jack, age 18, weight 70, height 178cm");
while (m1.find())
{
    System.out.printf("find %s\n", m1.group());
}
/*程序输出
find 18
find 70
find 178
*/

替换

Matcher对象支持替换操作的方法有:

  • replaceFirst
  • replaceAll
  • appendReplacement和appendTail

replaceFirst替换匹配到的第一个字符串,replaceAll替换所有匹配到的字符串,示例如下:

//替换第一个数字为0
Pattern p = Pattern.compile("[0-9]+");
Matcher m1 = p.matcher("name jack, age 18, weight 70, height 178cm");
String result = m1.replaceFirst("0");
System.out.println(result);
/*程序输出
name jack, age 0, weight 70, height 178cm
*/

//替换所有数字为0
Pattern p = Pattern.compile("[0-9]+");
Matcher m1 = p.matcher("name jack, age 18, weight 70, height 178cm");
String result = m1.replaceAll("0");
System.out.println(result);
/*程序输出
name jack, age 0, weight 0, height 0cm
*/

appendReplacement和appendTail提供了一种更灵活的方式来执行替换操作,和find()方法一起使用来定制每一个匹配到的字符串的替换方式。例如对每一个匹配到的字符串结尾加"0",示例如下:

//所有字符结尾加0替换
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher("name jack, age 18, weight 70, height 178cm");
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, m.group() + "0");
}
m.appendTail(sb);
System.out.println(sb.toString());
/*程序输出
name jack, age 180, weight 700, height 1780cm
*/

appendReplacement有两个参数一个是StringBuffer另一个是替换的字符串,它的执行过程为:

  • 把上一次匹配到的字符串和当前匹配到的字符串之间的内容添加到StringBuffer,不包含两个匹配到的字符串。如果是第一次匹配则从整个字符串的的起始位置开始。
  • 把替换字符串添加到StringBuffer,即把appendReplacement方法的第二个参数添加到StringBuffer。

appendTail用来把当前匹配到的字符串至整个字符串的结尾之间的内容添加到StringBuffer,不包含匹配到的字符串。

无论是replaceFirst还是replaceAll都无法实现上例中的功能,只有appendReplacement和appendTail可以实现该需求。

最后

使用正则表达式可以实现查找和替换功能,Pattern对象表示编译后的正则表达式,Matcher对象用来执行查找替换功能,Matcher对象常用的方法有:

  • matches方法表示正则表达式和整个输入字符串是否匹配。
  • lookingAt方法表示正则表达式和输入字符串的开头是否匹配。
  • find方法用来查找匹配正则表达式的所有字符串 。
  • group方法用来获取匹配到的字符串。
  • replaceAll执行全局的替换 。
  • replaceFirst只替换第一个匹配的字符串。
  • appendReplacement可以定制每一次替换。

【水煮Java】

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java正则表达式Pattern和Matcher 的相关文章

  • 使用“xargs”和“tar”进行“查找”

    我有以下想做的事情 find maxdepth 6 name tar gz o name bediskmodel o name src o name ciao o name heasoft o name firefly o name sta
  • Python ElementTree 模块:使用“find”、“findall”方法时如何忽略 XML 文件的命名空间来定位匹配元素

    我想用的方法findall定位源 xml 文件的某些元素ElementTree module 但是 源 xml 文件 test xml 具有命名空间 我截断了 xml 文件的一部分作为示例
  • SQL - 查找只喜欢同一年级学生的学生的年级

    我正在做一门免费的斯坦福在线课程 这很酷 你应该看看 在过去的两天里我一直在绞尽脑汁 但找不到以下问题的答案 请帮忙 问题4 查找只有同年级朋友的学生的姓名和成绩 返回按年级排序的结果 然后按每个年级中的名称排序 当我最终认为我得到了答案时
  • Scala 检查元素是否存在于列表中

    我需要检查列表中是否存在字符串 并调用相应接受布尔值的函数 是否可以通过一个衬垫来实现这一目标 下面的代码是我能得到的最好的 val strings List a b c val myString a strings find x gt x
  • 如何在Lua中隔离由空格分隔的非英语单词?

    我有这个字符串 Hello there this is some line aa 如何将其切片成这样的数组 Hello there this is some line aa 这是我到目前为止所尝试过的 function sliceSpace
  • Hamcrest Matchers 包含匹配器列表

    我正在尝试使用org hamcrest Matchers contains java util List gt http hamcrest org JavaHamcrest javadoc 1 3 org hamcrest Matchers
  • Unix 查找:多种文件类型

    我想对多种文件类型运行 find name 例如 find name h cpp 这可能吗 find name h o name cpp 要在以下位置找到此信息man页面 类型man find并通过键入搜索运算符 OPERATORS并按回车
  • 下划线充当分隔符 C# RTF Box

    我正在开发一个 Winforms 应用程序 并使用 RichTextBox 控件上的 Find 来查找要设置样式的特定关键字 由于某种原因 尽管指定了 WholeWord 标志 Find 似乎仍将其中带有下划线的单词视为 2 个单独的单词
  • find 命令仅搜索非隐藏目录

    在以下命令中 我只想搜索非隐藏的目录 如何使用以下命令执行此操作 我想在搜索日志文件时忽略隐藏目录 find home tom project name log txt ls home tom project dir1 dir2 backu
  • 查找早于 FILE 的文件而不包含 FILE

    我有一个计划要使用find给我一个比某些 FILE 更旧的文件列表 然后使用xargs or exec 将文件移动到其他地方 搬东西不是问题 xargs mv trash工作正常 现在 如果我尝试使用 newer FILE then FIL
  • MPL pos 是一个未记录的元函数吗?

    里面有下面的示例代码BOOST MPL 文档find算法 http www boost org doc libs 1 46 1 libs mpl doc refmanual find html typedef vector
  • 使用 VBA 选择“查找”的第二个结果

    我正在努力做到这一点 以便我可以找到 lights 的第二个结果 以防该术语出现各种情况 下面的代码查找所考虑范围内的第一个匹配项 Dim ws As Worksheet Dim rng1 As Range Dim y As Range C
  • 如何搜索包含2个特定字符串的所有文件?

    在我的 Visual Studio 中 我想找到包含 2 个特定单词的所有文件 例如 UpdatePanel and DropDownCheckList在解决方案或项目中 换句话说 我喜欢使用我自制的网络服务器控件来查找所有文件DropDo
  • 如何为 HDFS 递归列出子目录?

    我在 HDFS 中递归创建了一组目录 如何列出所有目录 对于普通的 UNIX 文件系统 我可以使用以下命令来做到这一点 find path type d print 但我想为 HDFS 得到类似的东西 递归列出目录内容hadoop dfs
  • 如何实现 hamcrest 匹配器

    我想运行这行代码 assertThat contextPin get equalTo pinPage getPinObjFromUi 但我想打印到日志中以提供信息 这意味着我可以知道哪些字段不相等 所以我想到了实现一个匹配器 我用谷歌搜索过
  • str.find 怎么这么快?

    我之前遇到过一个问题 我在迭代字符串并使用切片时寻找子字符串 原来这是一个really关于性能的坏主意 str find速度要快得多 但我不明白为什么 import random import string import timeit Ge
  • 在 Dart 中查找和替换字符串

    我正在为这个应用程序使用 flutter 但我在应用程序的逻辑方面遇到了问题 任何帮助深表感谢 应用程序目标 通过以下方式将所有输入缩写解码 替换 为单词 用户通过文本框输入文本 应用程序查找任何缩写 几个 并仅用文本替换缩写 我能够使用一
  • 使用 find 命令搜索直到第一个匹配项

    我只需要搜索可以在任何地方的特定目录有没有办法运行此命令直到第一个匹配 谢谢 我现在使用 find noleaf name experiment type d wc l 正如鲁道夫 米尔鲍尔 Rudolf M hlbauer 所提到的 qu
  • 朱莉娅在矩阵中查找(行,列)而不是索引

    在 Julia 中 您可以通过以下方式找到矩阵中元素的坐标 julia gt find x gt x 2 1 2 3 2 3 4 1 0 2 3 element Array Int64 1 2 4 9 这些值是正确的 但我更希望得到 row
  • 使用正则表达式模式查找 -name 并使用 cp 替换文件名

    目前我正在使用该命令cron复制 data从源到目标路径 find source path name data exec cp target path 源码结构为 source path category1 001 data source

随机推荐

  • 其他常用类

    1 Json和对象之间的转换 2 StringUtils StringUtils isNotBlank 判断不为空且也不是空字符串 3 BeanCopier BeanCopier是Cglib包中的一个类 用于对象的复制 net sf cgl
  • MySQL基础--(函数,函数返回值)

    含义 一组预先编译好的sql语句的集合 理解成成批的语句 1 提高代码的重用性 2 简化操作 3 减少编译次数并且减少和数据库服务器的连接次数 提高效率 区别 存储过程 可以有0个返回 也可以有多个返回 适合做批量插入 批量更新 函数 有且
  • Sqlserver递归查询所有上级或所有下级成员

    菜单目录结构表 create table tb menu id int not null 主键id title varchar 50 标题 parent int parent id 查找所有上级节点 with cte parent id t
  • Picgo使用Gitee平台搭建图床照片无法显示

    1 问题 使用Hexo框架搭建个人博客 发现博客中图片无法显示 2 问题分析 查看图床 发现相册中图片无法显示 查阅多方网站 发现Gitee与Picgo配合使用时 图片文件不能大于1M 这主要因为Gitee查阅超过1M的文件需要登录的权限
  • PCL中的区域生长分割(region growing segmentation)

    在本博文中 我主要介绍如何在pcl RegionGrowing类中调用区域增长算法 首先注意一点 这里是region growing segmentation 不是color based region growing segmentatio
  • sql server 数据库连接方式分析、详解

    先画一张概况图 OLEDB方式连接 Sql身份验证模式 Provider SQLOLEDB data source server name initial catalog databasename uid username pwd pass
  • 大厂面试题含答案(一)

    10家大厂面试题精选 2020 年阿里精选面试题及答案 1 使用 mysql 索引都有哪些原则 索引什么数据结构 B tree 和 B tree 什么区别 2 Mysql 有哪些存储引擎 请详细列举其区别 3 设计高并发系统数据库层面该如何
  • toFixed方法的小坑你知道吗?

    toFixed方法的小坑你知道吗 都知道toFixed 方法是可以四舍五入指定的小数位数的方法 但是他也是有坑的 其四舍五入的规则与数学中的规则不同 使用的是银行家舍入规则 其实就是一种四舍六入五取偶的规则 大概意思就是是 当小数点保留两位
  • 遇到“BUG: soft lockup - CPU#0 stuck for 22s”的解决思路

    之前开发的抓包模块上线后有客户反馈有丢包问题 这两天在定位这个丢包问题 抓包模块由我和另一名 队友 负责 我负责底层抓包开发 他负责接收处理 在测试丢包问题的时候 他遇到一个板子连不上的情况 问我咋回事 刚好看到了log打印一行 27468
  • Qt之进程通信-共享内存(含源码+注释)

    文章目录 一 内存共享示例图 读取文本 读取图片 二 界面操作共享内存示例图 文本读取示例图 图片读取示例图 弹窗示例图 二 个人理解与一些心得 三 源码 简易内存共享Demo 创建者 接收者 界面共享内存Demo 创建者 读取者 总结 相
  • 聊聊让开发头疼的一句话需求那些事

    一 引子 昨天接到一个朋友的电话 想委托我找人帮忙开发个产品 要求是要基于智能音箱使用的象微信聊天的聊天系统 二 需求分析 乍一听 站在产品的角度提这样的需求很合理 但仔细想想其实还有很多问题需要考虑 2 1 功能分析 聊天需要通信 首先需
  • 在线小说阅读网站开源项目地址整合

    项目开源地址 1 https github com ShanaMaid oho reader 小说数据接口地址 1 http api zhuishushenqi com book 50865988d7a545903b000009 留言评论样
  • Vue3【1.v-if 和 v-show 、2.动态组件、 3.网页的渲染 、4.v-for】

    文章目录 1 v if 和 v show 2 动态组件 3 网页的渲染 4 v for 4 1 v for 与对象 4 2 在 v for 里使用范围值 4 3 v for 与 v if 4 4 通过 key 管理状态 4 5 组件上使用
  • Android APP OpenGL ES应用(01)GLSurfaceView 2D/3D绘图基础

    1 Android 3D图形基础简介 1 1 OpenGL ES简介 OpenGL本身是开放图形库的一种标准 定义了一个跨语言 跨平台的编程规范 主要用于3D图形编程 OpenGLES是OpenGL的裁剪版本 主要是针对嵌入式设备 移动设备
  • layui 传递前端请求_基于Layui的页面传参及获取参数

    预计实现效果 通过点击编辑按钮 能够把该行数据显示在表格中 table html页面所属表格截取一行 edit html页面 实现代码 table html关键代码 传递参数 监听更新 编辑 操作 table on tool current
  • zookeeper集群扩容/下线节点实践

    环境 zookeeper版本 3 4 6 jdk版本 1 7 0 80 10 111 1 29 zk1 10 111 1 44 zk2 10 111 1 45 zk3 10 111 1 46 zk4 10 111 1 47 zk5 一 zo
  • python输出带有颜色的内容

    20200816 主要参考了文章 1 不使用第三方库 我当时的需求只需要将字体变色 比如输出 Error 其中Error为红色 def error print output print 033 31mError 033 0m output
  • strstr(str1,str2)函数使用 出现问题解析

    定义 strstr str1 str2 函数用于判断字符串str2是否是str1的子串 如果是 则该函数返回str2在str1中首次出现的地址 否则 返回NULL 定义说的有点羞涩难懂 举个例子就知道了 比如 char str2 cdef
  • 学习率与batch-size大小的关系

    近日训练的电脑从一个显卡升级到了4张显卡 这就意味着能够更快的训练速度 但是实际中 并不是这样的 多卡意味着可以使用大点的batch size 这样子会导致每个epoch收敛的更慢了 虽然说速度变快了 但是更新次数变少了 所以收敛的更慢了
  • Java正则表达式Pattern和Matcher

    Java字符串支持使用正则表达式进行替换和分隔操作 字符串提供的正则表达式操作是有限的 比如打印正则表达式匹配到的每一个字符串就无法通过字符串提供的方法来实现 Java使用Pattern和Matcher两个类来支持正则表达式功能 字符串提供