java 正则表达式

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

java 正则表达式

正则表达式是一个非常强大的字符串处理工具,通过一种特殊的语法来描述一种模式,再通过模式可以完成字符串的匹配,萃取,替换等操作

简例

要判断一个字符串是否是一个邮箱,可能需要很多的判断逻辑,使用则表达式,只需要下面代码即可

Pattern pattern = Pattern.compile("^([a-z0-9._%+-]+)@([a-z0-9.-]+)\\.[a-z]{2,4}$");
Matcher matcher = pattern.matcher("hatlonely@foxmail.com");
assertTrue(matcher.matches());

主要有 Pattern 对象和 Matcher 对象

  • Pattern: 模式对象
  • Matcher: 匹配的结果

部分匹配与完全匹配

Matcher 提供 matches 方法用于完全匹配,find 方法用于部分匹配,还提供 asPredicate 方法返回一个部分匹配的谓词

Pattern 提供一个静态方法 matches 用于完全匹配,这个方法会临时构造 Pattern 对象,如果 Pattern 会被多次重复使用,尽量别直接使用这种方法

assertTrue(Pattern.compile("hello").matcher("hello").matches());         // 完全匹配
assertTrue(Pattern.compile("hello").matcher("hello world").find());      // 部分匹配
assertTrue(Pattern.compile("hello").asPredicate().test("hello world"));  // 部分匹配
assertTrue(Pattern.matches("hello", "hello"));                           // 完全匹配

通配符

符号含义
c匹配单个字符 c
.匹配所有单个字符,换行符 \n 除外
^匹配字符串开始
$匹配字符串结束
\b匹配字符界,字符和空白之间
\B匹配非字符界,字符和空白之间
|匹配前面表达式或者后面表达式
[charset]匹配任意括号内的字符,可用 - 表示范围,[a-z] 表示所有小写字母
[^charset]匹配任意括号外的字符
\d匹配数字,相当于 [0-9]
\D匹配非数字,相当于 [^0-9]
\s匹配空白符,相当于 [ \f\n\r\t\v]
\S匹配非空白符,相当于 [^ \f\n\r\t\v]
\f匹配换页符
\n匹配换行符
\r匹配回车
\t匹配字表符
\v匹配垂直制表符
\w匹配字符类字符,包括下划线,相当于 [A-Za-z0-9_]
\W匹配非字符类字符,[^A-Za-z0-9_]
\u匹配四位十六进制数表示的 Unicode 字符,\u00A9 例如匹配 ©
\x匹配两位十六进制数表示的 ascii 码
限定符含义
*匹配前面字符或表达式 0 次或多次
+匹配前面字符或表达式 1 次或多次
?匹配前面字符或表达式 0 次或1次,跟着其他限定词后表示非贪婪匹配
{n}匹配前面字符或表达式 n 次
{n,}匹配前面字符或表达式至少 n 次
{n,m}匹配前面字符或表达式至少 n 次,至多 m 次
assertTrue(Pattern.matches("[0-9]*", ""));
assertTrue(Pattern.matches("[0-9]?", ""));
assertTrue(Pattern.matches("[0-9]?", "1"));
assertTrue(Pattern.matches("[0-9]+", "123"));
assertTrue(Pattern.matches("[0-9]{3}", "123"));
assertTrue(Pattern.matches("[0-9]{3,4}", "123"));
assertTrue(Pattern.matches("[0-9]{3,4}", "1234"));
assertTrue(Pattern.matches("[0-9]{3,}", "1234"));
assertTrue(Pattern.matches("\\d+", "123"));
assertTrue(Pattern.matches("\\s+", " \t"));
assertTrue(Pattern.matches("\\w+", "abc"));
assertTrue(Pattern.matches("(f|z)oo", "foo"));
assertTrue(Pattern.matches("(f|z)oo", "zoo"));
assertTrue(Pattern.matches(".*", "any string"));

捕获分组

支持用小括号 () 将模式分组,Matcher 提供 group 方法获取分组的内容

符号含义
(pattern)匹配分组并且捕获子表达式
(?:pattern)匹配分组但是不捕获子表达式

使用 groupCount 获取捕获分组的数量,由于下面例子中模式串中没有小括号,所以没有捕获的分组

Pattern pattern = Pattern.compile("^[a-z0-9]+@[a-z0-9.]+[.][a-z]{2,4}$");
Matcher matcher = pattern.matcher("hatlonely@foxmail.com");
assertTrue(matcher.matches());
assertEquals(matcher.groupCount(), 0);

使用 group 方法获取分组的内容,分组的编号以左括号为准,gruop(i) 返回第 i 个分组,group(0) 代表整个匹配串

Pattern pattern = Pattern.compile("^([a-z0-9]+)@(([a-z0-9.]+)[.]([a-z]{2,4}))$");
Matcher matcher = pattern.matcher("hatlonely@foxmail.com");
assertTrue(matcher.matches());
assertEquals(matcher.groupCount(), 4);
assertEquals(matcher.group(), "hatlonely@foxmail.com");
assertEquals(matcher.group(1), "hatlonely");
assertEquals(matcher.group(2), "foxmail.com");
assertEquals(matcher.group(3), "foxmail");
assertEquals(matcher.group(4), "com");

可以用 ?: 阻止捕获,如下面代码所示,foxmail.com 就没有被捕获

Pattern pattern = Pattern.compile("^([a-z0-9]+)@(?:([a-z0-9.]+)[.]([a-z]{2,4}))$");
Matcher matcher = pattern.matcher("hatlonely@foxmail.com");
assertTrue(matcher.matches());
assertEquals(matcher.groupCount(), 3);
assertEquals(matcher.group(), "hatlonely@foxmail.com");
assertEquals(matcher.group(0), "hatlonely@foxmail.com");
assertEquals(matcher.group(1), "hatlonely");
assertEquals(matcher.group(2), "foxmail");
assertEquals(matcher.group(3), "com");

预测

符号含义
(?=pattern)正向预测,非捕获匹配,匹配结束
(?!pattern)反向预测,非捕获匹配,匹配结束
(?<=pattern)正向预测,非捕获匹配,匹配开始
(?<!pattern)反向预测,非捕获匹配,匹配开始

正向预测是指匹配开始或者结束的字符串需要匹配(或者反向预测不能匹配)分组,分组内的模式仅用于预测,不会出现在最终的匹配串中,这种匹配只能用于部分匹配,?=?! 匹配开始,?<=?<! 匹配结束

{
    Pattern pattern = Pattern.compile("Windows (?=95|98|NT|2000)");
    Matcher matcher = pattern.matcher("Windows 2000");
    assertTrue(matcher.find());
    assertEquals(matcher.group(), "Windows ");
    assertEquals(matcher.groupCount(), 0);
}
{
    Pattern pattern = Pattern.compile("Windows (?!95|98|NT|2000)");
    Matcher matcher = pattern.matcher("Windows vista");
    assertTrue(matcher.find());
    assertEquals(matcher.group(), "Windows ");
    assertEquals(matcher.groupCount(), 0);
}
{
    Pattern pattern = Pattern.compile("(?<=95|98|NT|2000) Windows");
    Matcher matcher = pattern.matcher("2000 Windows");
    assertTrue(matcher.find());
    assertEquals(matcher.group(), " Windows");
    assertEquals(matcher.groupCount(), 0);
}
{
    Pattern pattern = Pattern.compile("(?<!95|98|NT|2000) Windows");
    Matcher matcher = pattern.matcher("vista Windows");
    assertTrue(matcher.find());
    assertEquals(matcher.group(), " Windows");
    assertEquals(matcher.groupCount(), 0);
}

反向引用

符号含义
\1匹配捕获匹配到的反向引用,\2 表示第二个反向引用

前面通过捕获获得的分组可以再后面引用,比如 (\w+) \1 表示两个重复的单词

assertTrue(Pattern.matches("(\\w+) \\1", "ab ab"));
assertTrue(Pattern.matches("(\\w+) \\1", "abc abc"));
assertFalse(Pattern.matches("(\\w+) \\1", "abc def"));

正则替换

StringPattern 都提供了 replaceAllreplaceFirst 方法来作正则替换,替换串中可以 $i 来获取正则匹配捕获的分组

Pattern pattern = Pattern.compile("^([a-z0-9]+)@(?:([a-z0-9.]+)[.]([a-z]{2,4}))$");
assertEquals(pattern.matcher("hatlonely@foxmail.com").replaceAll(
        "$0 $1 $2 $3"
), "hatlonely@foxmail.com hatlonely foxmail com");

assertEquals("hatlonely@foxmail.com".replaceAll(
        "^([a-z0-9]+)@(?:([a-z0-9.]+)[.]([a-z]{2,4}))$", "$0 $1 $2 $3"
), "hatlonely@foxmail.com hatlonely foxmail com");

搜索所有匹配

每次 find 调用都会匹配目标串中的一个匹配,通过多次 find 调用,可以找出目标串中所有的匹配

String str = "abab x acac y aeae";
Pattern pattern = Pattern.compile("(\\w+)\\1");
Matcher matcher = pattern.matcher(str);

List<String> li = new ArrayList<>();
while (matcher.find()) {
    li.add(matcher.group());
    assertThat(str.substring(matcher.start(), matcher.end()), equalTo(matcher.group()));
}
assertThat(li, equalTo(List.of("abab", "acac", "aeae")));

链接

深入java 定义正则表达式 这篇文章总结java1.4之后加入的正则表达式,总结他的使用。更多的源代码请访问我的github:https://github.com/yangsheng20080808/deepIntoJava本文分为3大部分 正则表达式的通用定义规则 正则表达式定义的例子 附加常用的匹配例子 正则表达式的通用定义规则使用正则表达式我们只要关心一个类即可:java.util.regex.Pattern 摘抄自官 阅读详情

相关推荐

LNA设计学习心得记录----MOS管的选取

LNA设计学习心得---MOS管的选取仿真

weixin_40359668的博客 6098

Pattern.compile函数提取字符串中指定的字符

字符串提取

梦幻通灵 5万+

工业以太网通讯Profinet协议详解

Profinet是通过西门子控制系统被广泛使用的工业通信协议,是一种较新的,基于以太网的工业通讯协议。

mydatai的专栏 8790

Java Pattern和Matcher字符匹配详解

Pattern类定义          public final class Pattern extends Object implementsSerializable正则表达式的编译表示形式。用于编译正则表达式后创建一个匹配模式。         指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。

知行流浪 4万+

代码技巧:Pattern.compile函数提取字符串中指定的字符(正则使用)

最近有个需求是要提取一段字符串中特定范围内的内容,查找资料后,使用的是Java中的Pattern.compile函数来实现对指定字符串的截取。记录下来查找的知识和应用,方便以后的查看。 Pattern.compile函数语法 // Pattern.compile函数语法 Pattern Pattern.compile(String regex, int flag) 知识学习 Pattern.compile函数中两个参数 regex 表示定义的规则 flag 表示设置的参数类型,主要包含以下几种情况: (

weixin_46120382的博客 6042

正则表达式Pattern和Matcher详解

使用步骤: 1. 将String类型的正则表达式传入Pattern.compile()中,生成Pattern对象,Pattern对象表示编译后的正则表达式 Pattern pattern = Pattern.compile("abc+"); //jdk解释:将给定的正则表达式编译到模式中。 2. 利用Pattern对象的matcher()生成Matcher对象,利用Matcher对象来...

android开发笔记 3013

Java正则表达式

一、简介: 正则表达式是检查、匹配字符串的表达式。 正则表达式是描述规则,主流语言都有良好的支持。 字符串校验、查找与替换是正则表达式的主要使用场景。 二、字符范围匹配: 正则表达式 说明 正确 错误 A 精准匹配单个字符 A a x | y 允许出现的2个字符 y n [ xyz ] 字符集合,允许出现集合内任意单个字符 z c [ a-z ] [ A-Z ] [ 0-9 ]

qq_43542011的博客 586

Java 正则表达式

介绍 前段时间使用Java正则表达式做一些字符串匹配的任务,现将学到的正则表达式的知识整理成文。 Java中Spring.class涉及到正则表达式。如Spring.split(), matches(),replaceAll()等方法。 Java中更一般使用正则表达式的方式是利用Pattern.class和Matcher.class,所在package为java.util.regex J...

学而不厌 诲人不倦 3万+

Java——正则表达式详解

Java正则表达式的支持是从1.4版本开始的,此前的JRE版本不支持正则表达式Java语言中的正则表达式匹配功能主要是通过和类实现的。find():在一个字符串里寻找一个给定模式的匹配:用一个给定的模式尝试匹配一个字符串的开头matches():用一个给定的模式去尝试匹配一个完整的字符串:进行替换操作,对所有的匹配都进行替换:进行替换操作,只对第一个匹配进行替换compile():把一个正则表达式编译成一个模式flags():返回某给定模式的匹配标志matches()

吴声子夜歌的博客 2万+

Java 基础篇】Java 正则表达式

本篇博客介绍了 Java 正则表达式的基本概念、语法和常用操作。我们学习了如何创建正则表达式模式对象、匹配器对象,以及如何使用它们进行字符串的匹配、提取和替换操作。正则表达式Java 程序中具有广泛的应用,可以帮助我们处理文本数据,提取关键信息,进行格式验证等。通过灵活运用正则表达式,我们可以更高效地处理字符串操作。希望本篇博客对你理解和使用 Java 正则表达式有所帮助。祝你在 Java 编程中取得更多的成功!

繁依Fanyi的博客 1万+

Java从入门到精通】Java 正则表达式

正则表达式定义了字符串的模式。正则表达式可以用来搜索、编辑或处理文本。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。Java 提供了 java.util.regex 包,它包含了 Pattern 和 Matcher 类,用于处理正则表达式的匹配操作。

RL2698853114的博客 1291

java正整数正则表达式_Java 正则表达式

Java 正则表达式正则表达式定义了字符串的模式。正则表达式可以用来搜索、编辑或处理文本。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。正则表达式实例一个字符串其实就是一个简单的正则表达式,例如 Hello World 正则表达式匹配 "Hello World" 字符串。.(点号)也是一个正则表达式,它匹配任何一个字符如:"a" 或 "1"。下表列出了一些正则表达式的实例及描述:正...

weixin_35652131的博客 4877

Java正则表达式——Java筑基

正则表达式并不仅仅局限于某种语言,但是在每个语言中都有差异。

qq_42544728的博客 2844
上一篇: java lambda 表达式
下一篇: java stream
hatlonely
博客等级 码龄14年 24粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值