Java正则表达式

java正则表达式

1、正则表达式的作用

​ 正则表达式定义了字符串的模式

​ 正则表达式可以用来搜索、编辑和处理文本

2、正则表达式的匹配规则

字符描述
\A匹配字符串开头
\b匹配一个字边界,即字与空格的位置,如“er\b”匹配“never”中的“er”,但不匹配“verb”中的“er”
\B匹配非字边界,如“er\b”匹配“verb”中的“er”,但不匹配“never”中的“er”
\d匹配数字字符,等效于[0-9]
\D匹配非数字字符,等效于[ ^ 0 - 9 ]
\f匹配换页符
\G匹配最后匹配完成的位置
\n匹配换行符
\r匹配一个回车符
\s匹配任何空白字符,包括空格、制表符、换页符、换行符等
\S匹配任何非空白字符
\t匹配制表符
\v匹配垂直制表符
\w匹配字母、数字、下划线
\W匹配非字母、数字、下划线
\z匹配字符串结尾,若存在换行,则只匹配到换行前的结束字符
\Z匹配字符串结尾,若存在换行,同时还会匹配换行符
^匹配输入字符串的开始位置
$匹配输入字符串的结尾位置
x|y匹配x或y
[xyz]字符集,匹配中括号中包含的任意一字符
[^xyz]反向字符集,匹配中括号中未包含的任意字符
[a-z]字符范围,匹配指定范围内的任何字符,如[a-z]匹配a到z范围内的任意字符
[^a-z]反向字符范围,匹配不在指定范围内的任何字符,如[ ^a-z ]匹配不在a到z范围内的任意字符
*匹配0个或多个前面的字符或表达式,如zo*与z和zo、zoo匹配,等价于{0,}
+匹配1个或多个前面的字符或表达式,如zo+与zo和zoo匹配,但无法和z匹配
匹配0个或1个前面的字符或表达式,如do(es)?与do或does匹配
{n}n是非负整数,匹配n次,如o{2}与Bob不匹配,但与food匹配
{n,}n是非负整数,至少匹配n次,如o{2,}与Bob不匹配,但与food、fooood匹配
{n,m}m,n是非负整数,且n<=m,至少匹配n次,至多匹配m次,如o{1,3}只能匹配foooooood中的前3个o

3、实例

1.手机号码:

​ 手机号码长11位,且总是以数组1开始的,我们直接写1就好,后面还有10位可以是0-9范围内的任意数字,那么我们可以用\d或[0-9]来表示,要匹配10次,我们可以在后面加上{10},因此最后的匹配串可以是^1\d{10}$或者^1[0-9]{10}$

2.IPV4地址:

​ IPV4 地址的格式是a.b.c.d,其中a,b,c,d是[0,255]上的任意数,a,b,c,d的考虑方式是一样的,因此我们拿出一个a来举例,[0,255]间的数可以是一位、两位或三位,如果是一位那么它可以是[0-9],如果是两位,那么可以是[1-9][0-9],如果是三位,可以是1[0-9]{2}|2[0-4][0-9]|25[0-5],那么合并起来就是[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5],数字之后是点“.”,我们需要用转义符写成\.,由于数字是个整体,所有我们用括号括起来,那么一个数字和一个点就表达成([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.,我们将这段字符重复三次后再加上一个[0-255]的数字即可,因此IPV4地址最终表示成(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])

4、java中的正则表达式

​ java中的正则表达式来自于java.util.regex包,该包中主要包括Pattern、Matcher、PatternSyntaxException三个类

Pattern类:

​ 用于表达和陈述所要搜索模式的对象,可以创建一个匹配模式,从源码中可以看到Pattern的构造函数时私有的,我们无法直接创建一个Pattern实例,

//Pattern构造函数源码
private Pattern(String p, int f) {
    pattern = p;
    flags = f;    // to use UNICODE_CASE if UNICODE_CHARACTER_CLASS present    
    if ((flags & UNICODE_CHARACTER_CLASS) != 0)
        flags |= UNICODE_CASE;    // Reset group index count
    capturingGroupCount = 1;
    localCount = 0;   
    if (pattern.length() > 0) {
        compile();
    } else {
        root = new Start(lastAccept);
        matchRoot = lastAccept; 
    }
}

​ 但我们可以用Pattern.compile(String regex)方法创建一个正则表达式,Compile是Pattern的类方法,有两个重载,通过简单工厂模式返回一个Pattern实例

public static Pattern compile(String regex) {
    return new Pattern(regex, 0);
}
public static Pattern compile(String regex, int flags) {
        return new Pattern(regex, flags);
}

​ 创建方式:

Pattern p = Pattern.compile("\\d+");
p.pattern();//返回正则表达式的字符串形式,即compile中的参数regex

​ Pattern.matches(CharSequence input)方法是一个类方法,可以用于检测字符串是否匹配给定的正则表达式,可以从源码中可以看到该函数最终还是通过调用Matcher的对象方法完成判断的

public static boolean matches(String regex, CharSequence input) {
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    return m.matches();
}

​ 然而这个方法是全局匹配的,即会匹配整个字符串,相当于传入的正则表达式为regex,但实际他做的事情是匹配^regex$,因此下面的三个匹配结果分别为true,false,false

System.out.println(Pattern.matches("\\d+","12"));
System.out.println(Pattern.matches("\\d+","12aa"));
System.out.println(Pattern.matches("\\d+","12aa12"));

pattern.matcher方法会返回一个Matcher实例,由于Matcher的构造器是包外不可见的,所以通常我们也只能通过pattern.matcher来获取Matcher的实例对象

public Matcher matcher(CharSequence input) {
    if (!compiled) {
        synchronized(this) {
            if (!compiled) 
                compile();       
        }    
    }   
    Matcher m = new Matcher(this, input); 
    return m;
}
Matcher类:

​ Matcher是一个匹配器类,是解释Pattern对Character sequence执行匹配操作的引擎,Matcher是一个Final类,因此无法被继承,且构造器是默认权限的,无法被包外的对象访问

    Matcher(Pattern parent, CharSequence text) {
        this.parentPattern = parent;
        this.text = text;

        // Allocate state storage
        int parentGroupCount = Math.max(parent.capturingGroupCount, 10);
        groups = new int[parentGroupCount * 2];
        locals = new int[parent.localCount];

        // Put fields into initial states
        reset();
    }

​ Matcher.matches()方法在上面提到了,他会对字符串进行全局匹配,只有整个字符串都匹配了才会返回true

​ Matcher.lookingAt()方法会对前面的字符串进行匹配,只有当匹配到的字符串在母串最前面才会返回true,例如以下代码输出的结果为true,false

Pattern p1 = Pattern.compile("\\d+a");
Pattern p2 = Pattern.compile("a\\d+");
Matcher m = p1.matcher("12aa12");
System.out.println(m.lookingAt());
m = p2.matcher("12aa12");
System.out.println(m.lookingAt());

​ Matcher.find()方法的要求则比较宽松,可以匹配到输入的字符串的任意子串,例如以下三种情况输出都为true:

Pattern p1 = Pattern.compile("\\d+a");
Pattern p2 = Pattern.compile("a\\d+");
Pattern p3 = Pattern.compile("\\d+");
Matcher m = p1.matcher("12aa12");
System.out.println(m.find());
m = p2.matcher("12aa12");
System.out.println(m.find());
m = p3.matcher("12aa12");
System.out.println(m.find());

​ Matcher.start()方法返回匹配到的子串第一个字符在母串中的索引位置

​ Matcher.end()方法返回匹配到的子串最后一个字符在母串中的索引位置

​ Matcher.group()方法返回匹配到的字符串

5、实例:

​ 以上面的IPV4地址为例:

public class MyRegex {   
    public static void main(String[] args) { 
        Pattern p = Pattern.compile("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])");    
        String url = "address:127.0.0.1(IPV4)";   
        Matcher m = p.matcher(url);     
        System.out.println("匹配结果:"+m.find()); 
        System.out.println("匹配到的字符串的开始位置:"+m.start());
        System.out.println("匹配到的字符串的结束位置:"+m.end());   
        System.out.println("匹配到的字符串:"+m.group());  
    }
}

​ 运行结果:

匹配结果:true
匹配到的字符串的开始位置:8
匹配到的字符串的结束位置:17
匹配到的字符串:127.0.0.1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值