正则表达式-RegularExpress

入门案例

提供了丰富的语法内容,正则表达式是分析检索文本内容的利器。

public class demo {
    public static void main(String[] args) {
        String content = "1992年我在广场吃炸鸡啊";
        String regex = "\\d\\d\\d\\d";
        //获取模式对象 pattern
        Pattern pattern = Pattern.compile(regex);
        //获取matcher构造器
        Matcher matcher = pattern.matcher(content);

        while(matcher.find()) {
            System.out.println(matcher.group(0));
        }



    }
}

 正则表达式底层实现

public class demo {
    public static void main(String[] args) {
        String content = "台上深情讲述、精彩1998纷呈,台下掌声雷动、气氛热烈,三十余位来自不同行业、不同领域,用奋斗承担青春使命之责、用奋斗谱写青春华章的杰出1998代表,围绕“青春奋斗”与莘莘学子对话青春、共叙成长,共赴一场激荡心灵的青春1998嘉年华。";
        // 1、\\d代表任意数字
        String regex = "\\d\\d\\d\\d";
        // 2、获取模式对象 pattern 即正则表达式对象
        Pattern pattern = Pattern.compile(regex);
        // 3、创建匹配器 matcher , 按照正则表达式的规则去匹配文本内容
        Matcher matcher = pattern.matcher(content);
        // 4、开始匹配
        
        while(matcher.find()) { // 寻找文本中与正则表达式匹配的内容,如果找到就返回true,否则返回false
            //该语句在正则表达式没有分组的情况下是固定写法 , 都是 group(0)
            System.out.println(matcher.group(0));
            //底层实现
            // matcher 类 , 有属性int groups[] , oldLast 
            // 在每次寻找过程中, 都要将符合正则表达式规定的规则的文本的开始索引存放到 groups[0]
            // 将末尾索引存放到 groups[1]。可以debug一下, 查看这个数组的变化,来验证
            // 调用group方法, 是将这两个索引之间的内容toString
            
            // 分组情况下写法,假设分了三组,写多了会抛出数组越界异常
//            while (matcher.find()) {
//                System.out.println(matcher.group(0)); // 实际返回的是groups [0] - groups[1]
//                System.out.println(matcher.group(1)); // 实际返回的是groups [2] - groups[3]
//                System.out.println(matcher.group(2)); // 实际返回的是groups [4] - groups[5]
//            }

            // group 方法源码
//            public String group(int group) {
//                if (first < 0)
//                    throw new IllegalStateException("No match found");
//                if (group < 0 || group > groupCount())
//                    throw new IndexOutOfBoundsException("No group " + group);
//                if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
//                    return null;
//                return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
//            }
        }
    }
}

元字符

转义字符 \\

说明: 在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义符号

则检索不到结果,甚至会报错的。


需要用到转义符号的字符有以下:*+()$/\?[]^{}

匹配符

符号符号示例解释
[    ]可接收的字符列表[efgh.!]

e、f、g、h、. 、!中的任意一个字符 

注意:中括号里的点号,感叹号不用转义。即中括号中的字符不需要转义

[^  ]不可接收的字符列表[^abc]除a、b、c之外的任意一个字符,包括数字和特殊符号
-连字符A-Z任意单个大写字母
符号含义示例说明匹配输入
.

匹配除了

\n以外的任何字符

a..b以a开头,b结尾,中间包括2个任意字符长度为4的字符串aaab、aefb、a35b、a#*b
\\d匹配单个数字字符,相当于[0-9]\\d{3}(\\d)?包括3个或4个数字的字符串123,9876
\\D匹配单个非数字字符,相当于[^0-9]\\D(\\d)*以单个非数字字符开头,后接任意个数字字符串a、A342
\\w匹配单个数字、大小写字母字符、相当于[0-9a-zA-Z]\\d{3}\\w{4}以3个数字字符开头的长度为7的数字字母字符串234abcd、12345pe
\\W匹配单个非数字、大小写字母字符,相当于[^0-9a-zA-Z]\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串#29、#?@10
\\s匹配任何空白符\\s\\t\\n\\r666
\\S匹配任何非空白符\\S\\t\\n\\r666

1.[a-z] 说明:
[a-z] 表示可以匹配a-z中任意一个字符,比如 [a-z] 、 [A-Z] 去匹配 a11c8 会得么结果?

2.java正则表达式默认是区分字母大小写的,如何实现不区分大小写
(?i)abc 表示abc都不区分大小写a(?i)bc 表示bc不区分大小写a((?i)b)c 表示只有b不区分大小写

Pattern pat = Pattern.compile(regEx, Pattern.CASE INSENSITIVE);\\不区分大小写

[A-Z] 表示可以匹配A-Z中任意一个字符.

[0-9] 表示可以匹配0-9中任意一个字符。

选择匹配符

在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个,这时要用到选择匹配符号

符号符号示例解释
|匹配“|”之前或之后的表达式ab|cdab或者cd

正则限定符

符号含义示例说明匹配输入
*指定字符重复0次或n次(无要求)零到多(abc)*仅包含任意个abc的字符串,等效于\w*abc、abcabc
+指定字符重复1次或n次(至少一次)1到多m+(abc)*以至少1个m开头,后接任意个abc的字符串
指定字符重复0次或1次(最多一次)0-1m+abc?以至少1个m开头,后接ab或abc的字符串mab、mabc、mmmab、mmabc
{n}只能输入n个字符[abcd]{3}由abcd中字母组成的任意长度为3的字符串abc 、dbc、adc
{n,}指定至少n个匹配[abcd]{3,}由abcd字母组成的任意长度不小于3的字符串aab、dbc、aaadbc
{n,m}指定至少n个但不多于m个匹配[abcd]{3,5}由abcd中字母组成的任意长度不小于3,不大于5的字符串abc、abcd、aaaaa、bcdab

定位符

符号含义示例说明匹配输入
^指定起始字符

^[0-9]+[a-z]*

以至少1个数字开头,后接任意个小写字母的字符串123、6aa、555edf
$指定结束字符^[0-9]\\-[a-z]+$以1个数字开头后接连字符“-”,并以至少1个小写字母结尾的字符串1-a
\\b匹配目标字符串的边界han\\b这里说的字符串的边界指的是子串间有空格,或者是目标字符串的结束位置hanshumahe sphan nnhan
\\B匹配目标字符串非边界han\\B和\b的含义刚刚相反hanwolovd jklajjkkk

分组、捕获

常用分组构造形式说明
(pattern)非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据做括号的顺序从1开始自动编号。
(?<name>pattern)命名捕获。将匹配的子字符串捕获到一个组名称或编号名称中。用于name的字符串不能包含任何标点符号,并且不能以数字开头,可以使用单引号代替尖括号,例如(?'name')

特别分组(非捕获匹配)

常用分组构造形式说明
(?:pattern)匹配patter但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于“or”字符(|)组合模式部件的情况有用。例如,‘industr(?:y|ies)’是比‘industry|industries’更经济的表达式
(?=pattern)它是一个非捕获匹配。例如,‘windows(?=95|98|NT|2000’匹配“windows2000”中的“Windows”,但不匹配“Windows3.1”中的“windows”.
(?!pattern)该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配。例如,‘windows(?=95|98|NT|2000’匹配“Windows 3.1”中的 “Windows”,但不匹配“Windows 2000”中的“Windows”。

非贪婪匹配

java正则表达式默认是贪婪匹配

练习

复杂URL验证

Pattern类与Matcher类

pattern类 :

matches() 方法 

直接调用静态方法Pattern.matches(string,string), 比较正则表达式regex,与content是否匹配(url判断)

Matcher类

start()方法,end () 方法

replaceall () 方法

public static void main(String[] args) {
String regex = "age";
String content = "agenameagename";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
System.out.println(matcher.replaceAll("年龄"));
}
}

输出

matches () 方法 

 反引用

遇到去重场景非常实用

 

 

 

String中支持正则表达式的方法 

replace () 替换

split() 截取

maches() 整体匹配验证、

练习

1.验证电子邮件格式是否合法 



1.规定电子邮件规则为只能有一个@
2.@前面是用户名,可以是a-z A-Z 0-9 _-字符
3.@后面是域名,并且域名只能是英文字母,比如 sohurcom 或者 tsinghua.org.cn

写出对应的正则表达式,验证输入的字符串是否为满足规则

  public static void main(String[] args) {
        String regex = "[\\w-]+@([a-zA-Z]+\\.)+[a-zA-Z]+";
        String content = "icando@qq.com";
        boolean b = content.matches(regex);
        System.out.println(b);

    }
}

2.要求验证是不是整数或者小数

提示:这个题要考虑正数和负数

比如:123 -345 34.89 -87.9 -0.01 0.45 等

  public static void main(String[] args) {
        //问题:验证一个数是整数还是小数, 提示:需要考虑正负数
        // 思路
        // 1.先写出一般情况
        // 2.再逐步完善
        String regex = "^[+-]*([1-9]\\d*|0)(\\.\\d+)?";
        String content = "-0.12";
        boolean b = content.matches(regex);
        System.out.println(b);

    }

3.对一个url进行解析 


https://www.sohucom:8080/abc/index.htm

要求得到

协议是什么?
域名是什么?
端口是什么?
文件名是什么?

 public static void main(String[] args) {
        String content = "http://www.baidu.com:8080/index.html";
        String regex = "^([a-zA-Z]+)://([a-zA-Z.]+):(\\d+)[\\w-/]*([\\w.]+)$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        if (matcher.matches()) {
            System.out.println("匹配成功");
            System.out.println("协议"+matcher.group(1));
            System.out.println("域名"+matcher.group(2));
            System.out.println("端口号"+matcher.group(3));
            System.out.println("文件名"+matcher.group(4));
        }
    }

注意: matches方法 中, 设置了group数组的数值,即分组在content中的下标 

输出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值