参考: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);
}
}