算法总结-正则表达式(正在更新)

参考:https://mp.weixin.qq.com/s/p14iXJ77mLG2BYe8gcqhfA

简述

正则表达式定义了字符串的模式,可以用来搜索、编辑或处理文本,正则表达式并不仅限于Java语言,其他语言中也存在,不过存在细微差别,Java正则表达式和Perl的最为相似,下面一起来看看吧:

正则表达式

java.util.regex 包的主要组成

(1)Pattern 类:

pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

(2)Matcher 类:

Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

(3)PatternSyntaxException:

PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

正则表达式的常见语法

$ 结束的位置
^ 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n"或"\r"之后的位置匹配
\ 转义字符,e.g:\.表示匹配小数点.,而不是任意字符,转义之后失去原有的功能
\n 换行符
\w 匹配包括字母数字下划线的任何单词字符
\W 与任何非单词字符匹配。与"[^A-Za-z0-9_]“等效
\s 表示空格制表符换行符
\b 匹配一个字边界,即字与空格间的位置。例如,“er\b"匹配"never"中的"er”,但不匹配"verb"中的"er”
\B 非字边界匹配。“er\B"匹配"verb"中的"er”,但不匹配"never"中的"er"
\d 数字字符匹配。等效于 [0-9]
\D 非数字字符匹配。等效于 [^0-9]
\s 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效
\S 匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效
\t 制表符匹配。与 \x09 和 \cI 等效

  • 匹配前面的子表达式任意次
    . 可以匹配任意字符
  • 表达式至少出现一次
    ? 表达式出现0次或者1次
    {10} 重复10次
    {1,3} 至少出现1次,至多出现3次
    [] 自定义集合,匹配其中的任意字符
    [^abc] 取非,除abc以外的任意字符
    | 将两个匹配条件进行逻辑或

实例解析

题目1:正则表达式匹配

题目描述:请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。
示例:
示例 1:"aaa"与模式"a.a"和"abaca"匹配
示例 2:"aaa"与"aa.a"和"aba"均不匹配
解题思路
当模式中的第二个字符是“
”时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。
如果字符串第一个字符跟模式第一个字符匹配,可以有3种匹配方式:
1、被忽略:模式后移2字符,相当于x被忽略;
2、匹配1位:字符串后移1字符,模式后移2字符;
3、匹配多位:字符串后移1字符,模式不变,即继续匹配字符下一位,因为
可以匹配多位;
当模式中的第二个字符不是“*”时:
1、如果字符串第一个字符和模式中的第一个字符相匹配,或者模式第一个字符为.时,那么字符串和模式都后移一个字符,然后匹配剩余的。
2、如果 字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。
递归终止条件:
1、str到尾部并且pattern也到尾部了,说明匹配成功
2、如果pattern匹配到尾部,str还未到尾部,说明匹配失败
注:下面代码可左右滑动查看

public class Solution {
    public boolean match(char[] str, char[] pattern){
        if(str == null || pattern == null){
            return false;
        }
        int strIndex = 0;
        int patternIndex = 0;
        return matchchCore(str,strIndex,pattern,patternIndex);
    }
    private boolean matchchCore(char[] str,int strIndex,char[] pattern,int patternIndex){
        //有效性检验,str到尾部并且pattern也到尾部了,说明匹配成功
        if(strIndex == str.length && patternIndex == pattern.length){
            return true;
        }
        //如果pattern匹配到尾部,str还未到尾部,说明匹配失败
        if(strIndex != str.length && patternIndex == pattern.length){
            return false;
        }
        
        if((patternIndex + 1 < pattern.length)&& pattern[patternIndex + 1] == '*'){
            if((strIndex < str.length && pattern[patternIndex] == str[strIndex]) || (strIndex < str.length && pattern[patternIndex] == '.')){
                return matchchCore(str,strIndex,pattern,patternIndex + 2)        //模式后移2,视为x*匹配0个字符
                    || matchchCore(str,strIndex + 1,pattern,patternIndex + 2)    //视为模式匹配1个字符
                    || matchchCore(str,strIndex + 1,pattern,patternIndex);       //*匹配多个字符,str后移一个字符,再进行匹配
            }else{
                return matchchCore(str,strIndex,pattern,patternIndex + 2);
            }
        }
        if((strIndex < str.length && pattern[patternIndex] == str[strIndex])||(strIndex < str.length && pattern[patternIndex] == '.')){
            return matchchCore(str,strIndex + 1,pattern,patternIndex + 1);
        }
        return false;
    }
}

题目2:特殊需求表达式

由26个英文字母组成的字符串:^[A-Za-z]+$

由26个大写英文字母组成的字符串:^[A-Z]+$

由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$

由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$

中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$

中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$

Email地址:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$

域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?

URL:^((http|https)?/)?([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$

手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}

18位身份证号:^(\d{6})(18|19|20)?(\d{2})([01]\d)([0123]\d)(\d{3})(\d|X|x)?$

帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$

强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$

日期格式:^\d{4}-\d{1,2}-\d{1,2}

一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$

一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$

xml文件:^([a-zA-Z]±?)+[a-zA-Z0-9]+\.[x|X][m|M][l|L]$

中文字符的正则表达式:[\u4e00-\u9fa5]

空白行的正则表达式:\n\s*\r (可以用来删除空白行)

首尾空白字符的正则表达式:^\s*|\s*KaTeX parse error: Expected group after '^' at position 3: 或(^̲\s*)|(\s*) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)

QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)

邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)

IP地址:\d+.\d+.\d+.\d+ (提取IP地址时有用)

钱的输入格式(“10000.00” 和 “10,000.00”, 和没有 “分” 的 “10000” 和 “10,000”):^[1-9][0-9]*$

题目3:JAVA正则表达式regex中方法的使用

注:下面代码可左右滑动查看

public class Test {  
  public static void main(String[] args) {  

       //电子邮件  
    String mailCheck = "^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";  
    Pattern mailRegex = Pattern.compile(mailCheck);  
    Matcher mailMatcher = mailRegex.matcher("ygc@qq.com");  
    boolean isMatched = mailMatcher.matches();  
    System.out.println(isMatched);  
  
       // 电话号码 
    String telCheck = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$"; 
    Pattern telRegex = Pattern.compile(telCheck); 
    Matcher telMatcher = telRegex.matcher("13555655606"); 
    boolean isMatched = telMatcher.matches(); 
    System.out.println(isMatched); 
  }  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值