正则表达式那些事?

1、简介

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

2、使用正则表达式的好处?

  1. 一个正则表达式就是一个描述规则的字符串
  2. 只需要编写正确的规则,就可以让正则表达式引擎去判断目标字符串是否符合规则
  3. 正则表达式是一套标准、可以用于任何语言
  4. JDK内置正则表达式引擎:java.util.regex
  5. 测试字符串内的模式——例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证
  6. 替换文本——可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它
  7. 基于模式匹配从字符串中提取子字符串——可以查找文档内或输入域内特定的文本

3、应用领域

正则表达式已经在很多软件中得到广泛的应用,主要有C#正则表达式、Java正则表达式、JavaScript正则表达式、Python正则表达式以及Ruby正则表达式等类型。

4、匹配规则

4.1、常规匹配规则

  • 精确匹配
  •  \d:0-9 
  • \w:a-z,A-Z,0-9,_ 
  • \s:空格,Tab键 
  • \D:非\d 
  • \W:非\w 
  • \S:非\s 
  • *:任意个字符 
  • +:至少一个字符 
  • ?:0个或1个字符
  •  {n}:n个字符 
  • {m,n}:m-n个字符 
  • {n,}:至少n个字符

4.2、复杂匹配规则

  • ^和$匹配开头和结尾

“^A\d{3}$”可以成功匹配:“A001”、“A999”;不可匹配:“B001”、“A0001”

  • […]可以匹配范围内的字符

"[abc]1"可以成功匹配:“a1”、“b1”、“c1”,不可匹配:“ab1”、“x1”

  • […]可以匹配范围内的字符

“[a-f]1”可以成功匹配:“a1”、“b1”、“f1”,不可匹配:“g1”、“ab1”

  • […]可以匹配范围内的字符

“[a-f0-9]{6}”可以成功匹配:“1a2b3c”、“ffffff”、“ff3434”,不可匹配:“abc12”、“A0000F”

  • [^…]可以匹配非范围内的字符

“[^0-9]{6}”可以成功匹配:“abcdef”、“$$$$$$”、“A-B-C”,不可匹配:“1abcde”、“A0000F”

4.3、分组匹配规则

如何编写正则表达式:

  • (…)可以分组:"(\d{4})\-(\d{1,2})\-(\d{1,2})"

"2020-03-06"——>“2020”    “03”   “06”

  • 提取电话号码###-########        "^(\d{3,4})\-(\d{6,8})$"

"010-1234567"——>"010"    "1234567"

"021-12345678"——>"021"    "12345678"

"0755-123456"——>"0755"    "123456"

  • 提取24小时时间##:##

^([0-1][0-9])|2[0-3])\:([0-5][0-9])$

  • 使用Matcher.group(n)可以快速提取子串:
Pattern pattern = Pattern.compile("^(\\d{3,4})\\-(\\d{6,8})$");
    Matcher matcher = pattern.matcher("010-12345678");
        if (matcher.matches()) {
        String whole = matcher.group(0); //0表示匹配的整个字符串
        String areaCode = matcher.group(1); //1表示匹配的第1个子串
        String telNumber = matcher.group(2);//2表示匹配的第2个子串
    }

正则表达式分组可以通过Matcher对象快速提取子串:

group(0)表示匹配的整个字符串

group(1)表示第1个子串

group(2)表示第2个子串

4.4、正则表达式匹配规则:

正则表达式规则可以匹配
A指定字符A
\u548c指定Unicode字符
.任意字符a,1,2,……,9
\d0~90,1,2,3,4,5,6,7,8,9
\w

                  a-z,A-Z,0~9,_

a,A,0,_,……
\s空格、Tab键""
\D非数字a,A,&,_,……
\W非\w&,@,中,……
\S非\s

a,A,&,_,……

AB*任意个数字符A,AB,ABB,ABBBB……
AB+至少1个字符AB,ABB,ABBB
AB?0个或1个字符A,AB
AB{3}指定个数字符ABBB
AB{1,3}指定范围个数字符AB,ABB,ABBB
AB{2,}至少n个字符ABB,ABBB,……
AB{0,3}最多n个字符A,AB,ABB,ABBB
^开头字符串开头
$结尾字符串结束
[ABC][…]内任意字符A,B,C
[A-F0-9xy]指定范围的字符A,……F,0,……9,x,y
[^A-F]指定范围外的任意字符非A,……,F
AB|CDAB或CDAB,CD
AB|CD|EFGAB或CD或EFGAB,CD,EFG

5、非贪婪匹配

  • 正则表达式匹配默认使用贪婪匹配
  • 使用?表示对某一规则进行非贪婪匹配
  • 注意区分?的含义

5.1、问题描述

给定一个字符串表示的数字,判断该数字末尾0的个数,例如:

“123000”:3个0

“10100”:2个0

“1001”:0个0

5.2、正则表达式默认使用贪婪匹配

尽可能多地向后匹配

static Pattern pattern = Pattern.compile("^(\\d+)(0*)$");
    Matcher matcher = pattern.matcher("123000");
        if (matcher.matches()) {
        matcher.group(1);    // "123000"
        matcher.group(2);   //  ""
    }

 使用?实现非贪婪匹配

static Pattern pattern = Pattern.compile("^(\\d+?)(0*)$");
    Matcher matcher = pattern.matcher("123000");
        if (matcher.matches()) {
        matcher.group(1);    // "123"
        matcher.group(2);   //  "000"
    }
static Pattern pattern = Pattern.compile("^(\\d??)(9*)$");
    Matcher matcher = pattern.matcher("9999");
        if (matcher.matches()) {
        matcher.group(1);    // ""
        matcher.group(2);   //  "9999"
    }

其中,\\d??中,第一个?表示“匹配0个或1个”;第二个?表示“非贪婪匹配”

 5.3、实现效果

public class RegexDemo {
    static Pattern pattern = Pattern.compile("^\\d+?(0*)$");
    public static int zeros(String s){
        Matcher matcher = pattern.matcher(s);
        if (matcher.matches()) {
            String zeroStr = matcher.group(1);
            return zeroStr.length();
        }
        throw  new IllegalArgumentException("Not a number");
    }
}


class RegexDemoTest {
    @Test
    public void testZeros() {
        assertEquals(0, RegexDemo.zeros("123456"));
        assertEquals(1, RegexDemo.zeros("123450"));
        assertEquals(2, RegexDemo.zeros("123400"));
        assertEquals(3, RegexDemo.zeros("123000"));
        assertEquals(4, RegexDemo.zeros("120000"));
        assertEquals(2, RegexDemo.zeros("100200"));
    }
}

 

小结

正则表达式是一个字符串

正则表达式用字符串描述一个匹配规则

使用正则表达式可以快速判断给定的字符串是否符合匹配规则

Java内建正则表达式引擎java.util.regex

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值