专栏首页SpringBoot图文教程恭喜你,Get到一份 正则表达式 食用指南

恭喜你,Get到一份 正则表达式 食用指南

先赞后看,养成习惯

前言

正则表达式

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

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

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

Java中正则表达式的使用

字符串内置正则

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

当仅且当正则匹配整个字符串时返回 true

示例代码

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

	        String[] array = "l b y".split("\\s");
	        for (String item : array) {
	            System.out.println(item);
	        }
	        System.out.println("----------");

	        System.out.println("l b y".replaceFirst("\\s", "-"));
	        System.out.println("----------");

	        System.out.println("l b y".replaceAll("\\s", "-"));

运行结果

true
----------
l
b
y
----------
l-b y
----------
l-b-y

regex包

java.util.regex 包主要包括以下三个类:

  1. Pattern 类 pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
  2. Matcher 类 Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
  3. PatternSyntaxException PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

Java 中regex 包使用正则表达式基本步骤

  1. 通过正则表达式创建模式对象 Pattern。
  2. 通过模式对象 Pattern,根据指定字符串创建匹配对象 Matcher。
  3. 通过匹配对象 Matcher,根据正则表达式操作字符串。

例如

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

public class TestRegex {
	public static void main(String[] args) {
		//定义一个字符串
		String text = "Hello Regex!";
		//创建一个Pattern对象  可以认为根据正则表达式获取一个对应的对象
        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());
        }
        
	}
}

运行的结果为:

Start index: 0 End index: 5 Hello

Start index: 6 End index: 11 Regex、

以上代码看不懂没有关系,提前感受一下正则的神奇,接下来我们学习一下正则表达式的的语法。

正则表达式的语法

常见匹配符号

匹配所有单个字符,除了换行符(Linux 中换行是 \n,Windows 中换行是 \r\n)

元字符

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

匹配一个数字,是 [0-9] 的简写

限定符

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

正则表达式

描述

举例

*

匹配 >=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 个数字

*?

如果 ? 是限定符 * 或 + 或 ? 或 {} 后面的第一个字符,那么表示非贪婪模式(尽可能少的匹配字符),而不是默认的贪婪模式

分组和反向引用

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

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

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

示例:

package com.baizhi.test;

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.
    }
}

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

否定先行断言(Negative lookahead)

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

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

a(?!b)

指定正则表达式的模式

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

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

Java 中的反斜杠

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

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

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

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

正则表达式常见应用示例

中文的匹配

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

public static void test3(){
		String str = "这里有个新手易范的错误,就是正angongsi";
        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
	}

数字范围的匹配

比如,匹配 1990 到 2017。

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

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

正确的匹配方式:

public static void test4(){
		String str = "1990\n2010\n2017\nsdfgadfggadfgdfgdfgafdgasfdga\n1998";
        // 这里应用了 (?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());
        }
	}

img 标签的匹配

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

public static void test5(){
		 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"));
	        }
	}

邮箱匹配

邮箱匹配的正则的写法有很多,这里给出一种参考的写法。

合法E-mail地址:

  1. 必须包含一个并且只有一个符号“@”
  2. 第一个字符不得是“@”或者“.”
  3. 不允许出现“@.”或者.@
  4. 结尾不得是字符“@”或者“.”
  5. 允许“@”前的字符中出现“+”
  6. 不允许“+”在最前面,或者“+@”

等等

示例代码

public static void test6(){
		 String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
	     Pattern regex = Pattern.compile(check);
	     Matcher matcher = regex.matcher("dffdfdf@qq.com");
	     boolean isMatched = matcher.matches();
	     System.out.println(isMatched);
	}

手机号匹配

	public static void test7(){
		String check = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\\d{8}$";
	     Pattern regex = Pattern.compile(check);
	     Matcher matcher = regex.matcher("18638693953");
	     boolean isMatched = matcher.matches();
	     System.out.println(isMatched);
	}

url匹配

public static void test8(){
		String url = "http://www.lubingyang.com/";
		String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?";
		boolean isMatched = Pattern.matches(regex, url);
		System.out.println(isMatched);
	}

本文分享自微信公众号 - 鹿小洋的Java笔记(lulaoshiJava),作者:鹿老师

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringBoot图文教程3—「‘初恋’情结」集成Jsp

    通过前面两篇,小伙伴们已经成功的实现了增删改查,但是,没有页面效果的项目,就像网恋没有奔现的小姐姐一样,安能辨她是雌雄。今天用SpringBoot整合Jsp页面...

    鹿老师的Java笔记
  • SpringBoot图文教程4—SpringBoot 实现文件上传下载

    通过前面三篇的教程,小伙伴们已经可以实现一个web项目了,但是现在项目的功能还有点简单,接下来的文章中将会逐步完善添加新的功能。

    鹿老师的Java笔记
  • 什么?接口中方法可以不是抽象的「JDK8接口新语法的深度思考」

    在传统的接口语法中,接口中只可以有抽象方法。在是在实际的使用中,我们往往会需要用到很多和接口相关的功能(方法),这些功能会单独的拿出开放在工具类中。

    鹿老师的Java笔记
  • Easyui学习整理笔记

    SmileNicky
  • Python关键词数据采集案例,5118查询网站关键词数据采集

    对于seoer而言,关注网站的关键词数据是非常重要的,关键词排名情况,流量来源,以及同行的网站数据,那么借助于seo查询工具也是非常有必要的,比较知名的就有爱站...

    二爷
  • 快速学习Oracle-存储函数

    一般来讲,过程和函数的区别在于函数可以有一个返回值;而过程没有返回值。但过程和函数都可以通过 out 指定一个或多个输出参数。我们可以利用 out 参数,在过程...

    cwl_java
  • 编程小白 | 每日一练(130)

    这道理放在编程上也一并受用。在编程方面有着天赋异禀的人毕竟是少数,我们大多数人想要从编程小白进阶到高手,需要经历的是日积月累的学习,那么如何学习呢?当然是每天都...

    闫小林
  • 编程赚钱的7个方法

      几个星期前,当我收到一个自称Someone712的人发给我的一条消息时,我决定要写一篇如何用编程赚钱的博客文章。Someone712: 我对电子、物理和编程...

    用户1289394
  • 我很想学编程,但看不懂编程代码怎么办?

    从事编程开始十几年,面试过很多初级学习编程的人,几乎每个人都有一种所谓的编程情怀,觉得编程非常有意思,想着去学习编程,所以开始看不懂编程代码是一件非常正常的事情...

    程序员互动联盟
  • 编程小白 | 每日一练(21)

    这道理放在编程上也一并受用。在编程方面有着天赋异禀的人毕竟是少数,我们大多数人想要从编程小白进阶到高手,需要经历的是日积月累的学习,那么如何学习呢?当然是每天都...

    闫小林

扫码关注云+社区

领取腾讯云代金券