Java 正则表达式匹配

这篇具有很好参考价值的文章主要介绍了Java 正则表达式匹配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 正则表达式

1.1 什么是正则表达式

正则表达式: 定义一个搜索模式的字符串。

正则表达式可以用于搜索、编辑和操作文本。

正则对文本的分析或修改过程为:首先正则表达式应用的是文本字符串(text/string),它会以定义的模式从左到右匹配文本,每个源字符只匹配一次。

1.2 示例

正则表达式 匹配
this is text 精确匹配字符串 "this is text"
this\s+is\s+text 匹配单词 "this" 后跟一个或多个空格字符,后跟词 "is" 后跟一个或多个空格字符,后跟词 "text"
^\d+(\.\d+)? ^ 定义模式必须匹配字符串的开始,d+ 匹配一个或多个数字,? 表明小括号内的语句是可选的,\. 匹配 ".",小括号表示分组。例如匹配:"5"、"1.5" 和 "2.21"

2 正则表达式的编写规则

2.1 常见匹配符号

正则表达式 描述
. 匹配所有单个字符,除了换行符(Linux 中换行是 \n,Windows 中换行是 \r\n
^regex 正则必须匹配字符串开头
regex$ 正则必须匹配字符串结尾
[abc] 复选集定义,匹配字母 a 或 b 或 c
[abc][vz] 复选集定义,匹配字母 a 或 b 或 c,后面跟着 v 或 z
[^abc] 当插入符 ^ 在中括号中以第一个字符开始显示,则表示否定模式。此模式匹配所有字符,除了 a 或 b 或 c
[a-d1-7] 范围匹配,匹配字母 a 到 d 和数字从 1 到 7 之间,但不匹配 d1
XZ 匹配 X 后直接跟着 Z
X|Z 匹配 X 或 Z

2.2 元字符

元字符是一个预定义的字符。

正则表达式 描述
\d 匹配一个数字,是 [0-9] 的简写
\D 匹配一个非数字,是 [^0-9] 的简写
\s 匹配一个空格,是 [ \t\n\x0b\r\f] 的简写
\S 匹配一个非空格
\w 匹配一个单词字符(大小写字母、数字、下划线),是 [a-zA-Z_0-9] 的简写
\W 匹配一个非单词字符(除了大小写字母、数字、下划线之外的字符),等同于 [^\w]

2.3 限定符

限定符定义了一个元素可以发生的频率。

正则表达式 描述 举例
* 匹配 >=0 个,是 {0,} 的简写 X* 表示匹配零个或多个字母 X,.* 表示匹配任何字符串
+ 匹配 >=1 个,是 {1,} 的简写 X+ 表示匹配一个或多个字母 X
? 匹配 1 个或 0 个,是 {0,1} 的简写 X? 表示匹配 0 个或 1 个字母 X
{X} 只匹配 X 个字符 \d{3} 表示匹配 3 个数字,.{10} 表示匹配任何长度是 10 的字符串
{X,Y} 匹配 >=X 且 <=Y 个 \d{1,4} 表示匹配至少 1 个最多 4 个数字
*? 如果 ? 是限定符 * 或 + 或 ? 或 {} 后面的第一个字符,那么表示非贪婪模式(尽可能少的匹配字符),而不是默认的贪婪模式

2.4 分组和反向引用

小括号 () 可以达到对正则表达式进行分组的效果。

模式分组后会在正则表达式中创建反向引用。反向引用会保存匹配模式分组的字符串片断,这使得我们可以获取并使用这个字符串片断。

在以正则表达式替换字符串的语法中,是通过 $ 来引用分组的反向引用,$0 是匹配完整模式的字符串(注意在 JavaScript 中是用 $& 表示);$1 是第一个分组的反向引用;$2 是第二个分组的反向引用,以此类推。

示例:


public class RegexTest {

    public static void main(String[] args) {
        // 去除单词与 , 和 . 之间的空格
        String Str = "Hello , World .";
        String pattern = "(\\w)(\\s+)([.,])";
        // $0 匹配 `(\w)(\s+)([.,])` 结果为 `o空格,` 和 `d空格.`
        // $1 匹配 `(\w)` 结果为 `o` 和 `d`
        // $2 匹配 `(\s+)` 结果为 `空格` 和 `空格`
        // $3 匹配 `([.,])` 结果为 `,` 和 `.`
        System.out.println(Str.replaceAll(pattern, "$1$3")); // Hello, World.
    }
}

上面的例子中,我们使用了 [.] 来匹配普通字符 . 而不需要使用 [\\.]。因为正则对于 [] 中的 .,会自动处理为 [\.],即普通字符 . 进行匹配。

2.4.1 仅分组但无反向引用

当我们在小括号 () 内的模式开头加入 ?:,那么表示这个模式仅分组,但不创建反向引用。

示例:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String str = "img.jpg";
        // 分组且创建反向引用
        Pattern pattern = Pattern.compile("(jpg|png)");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.group(1));
        }
    }
}

运行结果:

jpg jpg

若源码改为:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String str = "img.jpg";
        // 分组但不创建反向引用
        Pattern pattern = Pattern.compile("(?:jpg|png)");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.group(1));
        }
    }
}

运行结果:

jpg
Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 1
    at java.util.regex.Matcher.group(Matcher.java:538)
    at com.wuxianjiezh.regex.RegexTest.main(RegexTest.java:15)

2.4.2 分组的反向引用副本

Java 中可以在小括号中使用 ?<name> 将小括号中匹配的内容保存为一个名字为 name 的副本。

示例:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String str = "@wkf 你好啊";
        Pattern pattern = Pattern.compile("@(?<first>\\w+\\s)"); // 保存一个副本
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
            System.out.println(matcher.group(1));
            System.out.println(matcher.group("first"));
        }
    }
}

运行结果:

@wkf
wkf 
wkf 

2.5 否定先行断言(Negative lookahead)

我们可以创建否定先行断言模式的匹配,即某个字符串后面不包含另一个字符串的匹配模式。

否定先行断言模式通过 (?!pattern) 定义。比如,我们匹配后面不是跟着 "b" 的 "a":

a(?!b)

2.6 指定正则表达式的模式

可以在正则的开头指定模式修饰符。

  • (?i) 使正则忽略大小写。
  • (?s) 表示单行模式("single line mode")使正则的 . 匹配所有字符,包括换行符。
  • (?m) 表示多行模式("multi-line mode"),使正则的 ^ 和 $ 匹配字符串中每行的开始和结束。

2.7 Java 中的反斜杠

反斜杠 \ 在 Java 中表示转义字符,这意味着 \ 在 Java 拥有预定义的含义。

这里例举两个特别重要的用法:

  • 在匹配 . 或 { 或 [ 或 ( 或 ? 或 $ 或 ^ 或 * 这些特殊字符时,需要在前面加上 \\,比如匹配 . 时,Java 中要写为 \\.,但对于正则表达式来说就是 \.
  • 在匹配 \ 时,Java 中要写为 \\\\,但对于正则表达式来说就是 \\

注意:Java 中的正则表达式字符串有两层含义,首先 Java 字符串转义出符合正则表达式语法的字符串,然后再由转义后的正则表达式进行模式匹配。

2.8 易错点示例

  • [jpg|png] 代表匹配 j 或 p 或 g 或 p 或 n 或 g 中的任意一个字符。
  • (jpg|png) 代表匹配 jpg 或 png

3 在字符串中使用正则表达式

3.1 内置的字符串正则处理方法

在 Java 中有四个内置的运行正则表达式的方法,分别是 matches()split())replaceFirst()replaceAll()。注意 replace() 方法不支持正则表达式。

方法 描述
s.matches("regex") 当仅且当正则匹配整个字符串时返回 true
s.split("regex") 按匹配的正则表达式切片字符串
s.replaceFirst("regex", "replacement") 替换首次匹配的字符串片段
s.replaceAll("regex", "replacement") 替换所有匹配的字符

3.2 代码示例 

public class RegexTest {

    public static void main(String[] args) {
        System.out.println("wxj".matches("wxj"));
        System.out.println("----------");

        String[] array = "w x j".split("\\s");
        for (String item : array) {
            System.out.println(item);
        }
        System.out.println("----------");

        System.out.println("w x j".replaceFirst("\\s", "-"));
        System.out.println("----------");

        System.out.println("w x j".replaceAll("\\s", "-"));
    }
}

 运行结果:

true
----------
w
x
j
----------
w-x j
----------
w-x-j

4 模式和匹配

Java 中使用正则表达式需要用到两个类,分别为 java.util.regex.Pattern 和 java.util.regex.Matcher

第一步,通过正则表达式创建模式对象 Pattern

第二步,通过模式对象 Pattern,根据指定字符串创建匹配对象 Matcher

第三步,通过匹配对象 Matcher,根据正则表达式操作字符串。

来个例子,加深理解:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String text = "Hello Regex!";

        Pattern pattern = Pattern.compile("\\w+");
        // Java 中忽略大小写,有两种写法:
        // Pattern pattern = Pattern.compile("\\w+", Pattern.CASE_INSENSITIVE);
        // Pattern pattern = Pattern.compile("(?i)\\w+"); // 推荐写法
        Matcher matcher = pattern.matcher(text);
        // 遍例所有匹配的序列
        while (matcher.find()) {
            System.out.print("Start index: " + matcher.start());
            System.out.print(" End index: " + matcher.end() + " ");
            System.out.println(matcher.group());
        }
        // 创建第两个模式,将空格替换为 tab
        Pattern replace = Pattern.compile("\\s+");
        Matcher matcher2 = replace.matcher(text);
        System.out.println(matcher2.replaceAll("\t"));
    }
}

运行结果:

Start index: 0 End index: 5 Hello
Start index: 6 End index: 11 Regex
Hello    Regex!

5 若干个常用例子

5.1 中文的匹配

[\u4e00-\u9fa5]+ 代表匹配中文字。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String str = "这是中文";
        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

运行结果:

这是中文

5.2 数字范围的匹配

比如,匹配 1990 到 2017。

注意:这里有个新手易范的错误,就是正则 [1990-2017],实际这个正则只匹配 0 或 1 或 2 或 7 或 9 中的任一个字符。

正则表达式匹配数字范围时,首先要确定最大值与最小值,最后写中间值。

正确的匹配方式:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String str = "1990\n2010\n2017";
        // 这里应用了 (?m) 的多行匹配模式,只为方便我们测试输出
        // "^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$" 为判断 1990-2017 正确的正则表达式
        Pattern pattern = Pattern.compile("(?m)^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

运行结果:

1990
2010
2017

5.3 img 标签的匹配

比如,获取图片文件内容,这里我们考虑了一些不规范的 img 标签写法:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String str = "<img  src='aaa.jpg' /><img src=bbb.png/><img src=\"ccc.png\"/>" +
                "<img src='ddd.exe'/><img src='eee.jpn'/>";
        // 这里我们考虑了一些不规范的 img 标签写法,比如:空格、引号
        Pattern pattern = Pattern.compile("<img\\s+src=(?:['\"])?(?<src>\\w+.(jpg|png))(?:['\"])?\\s*/>");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group("src"));
        }
    }
}

运行结果:

aaa.jpg
bbb.png
ccc.png

5.4 贪婪与非贪婪模式的匹配

比如,获取 div 标签中的文本内容:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

    public static void main(String[] args) {
        String str = "<div>文章标题</div><div>发布时间</div>";
        // 贪婪模式
        Pattern pattern = Pattern.compile("<div>(?<title>.+)</div>");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group("title"));
        }

        System.out.println("--------------");

        // 非贪婪模式
        pattern = Pattern.compile("<div>(?<title>.+?)</div>");
        matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group("title"));
        }
    }
}

运行结果:文章来源地址https://www.toymoban.com/news/detail-739924.html

文章标题</div><div>发布时间
--------------
文章标题
发布时间

6 推荐两个在线正则工具

  • JavaScript、Python 等的在线表达式工具:https://regex101.com/
  • Java 在线表达式工具:http://www.regexplanet.com/advanced/java/index.html

到了这里,关于Java 正则表达式匹配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java中通过split方法使用分号分割,使用正则表达式匹配不识别单引号中的分号

    在Java中,使用split()方法可以通过指定正则表达式作为分隔符来拆分字符串。如果你想忽略单引号内的分号,可以使用以下代码: 在这个正则表达式中,它使用反向零宽断言 (?!...) 和顺序零宽断言 (?=...) 来限制分隔符的匹配位置,以确保只有在非单引号内部的位置才会进行分

    2024年02月08日
    浏览(36)
  • 【正则表达式】正则表达式常见匹配模式

    模式 描述 w 匹配字母数字及下划线 W 匹配非字母数字下划线 s 匹配任意空白字符,等价于 [tnrf]. S 匹配任意非空字符 d 匹配任意数字,等价于 [0-9] D 匹配任意非数字 A 匹配字符串开始 Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串 z 匹配字符串结

    2024年02月09日
    浏览(61)
  • Java 之正则表达式语法及常用正则表达式汇总

    正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为 regex、regexp 或 RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称

    2024年02月09日
    浏览(53)
  • 正则表达式 (用于灵活匹配文本的表达式)

    目录 . * 用于匹配任意单个字符,除了换行符。 例如使用正则表达式 a.b, 它可以匹配aab、acb、a#b 用于匹配前一个字符零次或多次。 例如,使用正则表达式 ab*c ,它可以匹配 \\\"ac\\\"、\\\"abc\\\"、\\\"abbc\\\",因为 b* 表示匹配零个或多个字符 \\\"b\\\"。所以,这个表达式可以匹配 \\\"ac\\\"(零个 \\\"b\\\"),

    2024年01月16日
    浏览(48)
  • 【Java】 java | 正则 | 正则表达式 | 强密码

    1、需要验证密码强度 2、使用正则 3、正则 4、java示例

    2024年02月07日
    浏览(35)
  • Java 正则表达式

    正则表达式的元字符可以大致分为六类: 限定符 选择匹配符 分组组合和反向引用符 特殊字符 字符匹配符 定位符 转义符 \\\\ 符号在检索某些特殊字符的时候可以使用,否则检索不到结果。 在Java中是 \\\\ ,而其他语言则是 。 一般 . * + ( ) $ / ? [ ] { } 都可能需要转义符 符号

    2024年02月21日
    浏览(95)
  • Java正则表达式

    正则表达式 能够理解正则表达式的作用 能够使用正则表达式的字符类 能够使用正则表达式的逻辑运算符 能够使用正则表达式的预定义字符类 能够使用正则表达式的限定符 能够使用正则表达式的分组 能够在String的split方法中使用正则表达式 在Java中,我们经常需要验证一些

    2024年01月19日
    浏览(31)
  • 正则表达式(Java)

    正则表达式是由一些特定的字符组成,代表一个规则,可以用来检验数据格式是否合法,也可以在一段文本中查找满足要求的内容。 如果使用代码检验数据是否正确: 使用正则表达式: String提供了一个匹配正则表达式的方法:  图片来源heimait \\\\d才会当成d使用 (?i)表示忽略大

    2024年02月20日
    浏览(37)
  • 正则表达式(JAVA)

    正则表达式在用于 校验信息 是否 满足某些规则 的时候,非常的好用 在 文本中查找 满足要求的内容 符号 作用 补充 [abc] 只能是a,b或c 匹配的一个字符只能是 [] 范围内的其中一个 [^abc] 除了a,b,c之外的任何字符 ^ 符号类似 非 [a-zA-Z] a到z A到Z ,包括范围 - 作用是由…到… ,两个或

    2024年02月10日
    浏览(29)
  • JAVA系列---正则表达式

    编号 元字符 匹配功能 1 . 匹配除换⾏符以外的任意字符 2 w 匹配字⺟或数字或下划线 3 s 匹配任意的空⽩符 4 d 匹配数字 5 n 匹配⼀个换⾏符 6 t 匹配⼀个制表符 7 ^ 匹配字符串的开始 8 $ 匹配字符串的结尾 9 W 匹配⾮字⺟或数字或下划线 10 D 匹配⾮数字 11 S 匹配⾮空⽩符

    2024年02月15日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包