概念
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本
为什么学?
我们在网上扒取html的时候会有很多的标签,那么怎么把一些有规律的标签内容给获取出来了,总不能一个一个的找吧。
但是正则表达式很难学,但是却非常的有用。
正则表达式中常用的字符含义
用法
s.matches()
1.普通字符和10个元字符:
元字符 | 用法 | 写法(以abc为例子) | 以abc为例子(可以匹配的类型) |
---|---|---|---|
普通字符 | 匹配自身 | abc | abc |
. | 匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符 | a.c | abc |
\ | 转义字符,使后一个字符改变原来的意思 | a.c;a\c | a.c;a\c |
* | 匹配前一个字符0或多次 | abc* | abccc |
+ | 匹配前一个字符1次或无限次 | abc+ | abccc |
? | 匹配一个字符0次或1次 | abc? | ab;abc |
^ | 匹配字符串开头。在多行模式[]中匹配每一行的开头 | ^abc | abc |
| | 或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式 | abc|def | abc,def |
{} | {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次 | ab{1,2}c | abbc |
[] | 字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。所有特殊字符在字符集中都失去其原有的特殊含义。用\反斜杠转义恢复特殊字符的特殊含义。 | a[bcd]e | abe,ace,ade |
() | 被括起来的表达式将作为分组,从表达式左边开始每遇到一个分组的左括号“(”,编号+1.分组表达式作为一个整体,可以后接数量词。表达式中的、 | 仅在该组中有效。 | (abc){2},a(123|456)c,abcabc,a456c |
在这里 , 强调下反斜杠\的作用:
1)反斜杠后边跟元字符去除特殊功能;(即将特殊字符转义成普通字符)
2)反斜杠后边跟普通字符实现特殊功能;(即预定义字符)
3)引用序号对应的字组所匹配的字符串。
我们先测试一下,然后写个示例,判断手机号的示例
String s = "132465";
// ? 一次/一次都没有 false
boolean b0 = s.matches("\\d?");
System.out.println(b0);
//* 零次/多次 true
boolean b1 = s.matches("\\d*");
System.out.println(b1);
//+ 一次/多次
boolean b2 = s.matches("\\d+");
System.out.println(b2);
//{m} 恰好m次(5) false
boolean b3 = s.matches("\\d{5}");
System.out.println(b3);
//{m,} 至少m次(5) true
boolean b4 = s.matches("\\d{5,}");
System.out.println(b4);
//{m,n} 至少m次(5),最多n次(6) true
boolean b5 = s.matches("\\d{5,6}");
System.out.println(b5);
咋们以判断手机号码为例:
首先手机号的长度是11
第一位肯定是1吧,这个直接写死
第二位是3,5,7,8,9其中的一个
后面9位就没有其他要求,只要是0-9的数组即可
Scanner phoneNum = new Scanner(System.in);
while (true) {
System.out.print("请输入您的电话号码: ");
String isNum = phoneNum.next();
if (isNum.matches("[1][35789]\\d{9}")) {
System.out.println("您输入的手机号是正确的.");
break;
} else {
System.out.print("您输入的手机号有误, ");
}
}
//结果
请输入您的电话号码: 136191262
您输入的手机号有误, 请输入您的电话号码: 136191262574
您输入的手机号有误, 请输入您的电话号码: 13619126257
您输入的手机号是正确的.
2.预定义字符集
预定义字符集 | 用法 | 写法(以abc为例子) | 以abc为例子(可以匹配的类型) |
---|---|---|---|
\d | 数字:[0-9] | a\dc | a1c |
\D | 非数字:[^\d] | a\Dc | abc |
\s | 匹配任何空白字符:[<空格>\t\r\n\f\v] | a\sc | a c |
\S | 非空白字符:[^\s] | a\Sc | abc |
\w | 匹配包括下划线在内的任何字字符:[A-Za-z0-9_] | a\wc | abc |
\W | 匹配非字母字符,即匹配特殊字符 | a\Wc | a c |
\A | 仅匹配字符串开头,同^ | \Aabc | abc |
\Z | 仅匹配字符串结尾,同$ | abc\Z | abc |
\b | 匹配\w和\W之间,即匹配单词边界匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 | \babc,\ba,\b!bc | 空格abc空格,a!bc |
\B | 匹配非单词边界 | a\Bbc | abc |
同样,我们先来一个一个测试一下,然后做个整合,写个判断邮箱的例子.
String s = "332bsad_";
// D 非数字 false
boolean b0 = s.matches("\\D*");
System.out.println(b0);
// s 空白字符 false
boolean b1 = s.matches("\\s*");
System.out.println(b1);
// S 非空白字符 true
boolean b2 = s.matches("\\S*");
System.out.println(b2);
// w 大小写字母,下划线,数字 true
boolean b3 = s.matches("\\w*");
System.out.println(b3);
// W 特殊字符 false
boolean b4 = s.matches("\\W*");
System.out.println(b4);
同样,我们以邮箱为例:
邮箱有qq号+@qq.com,也有手机号+@163.com等等,QQ号最短5位,一般都是10位,手机号是11位,那么咋们就可以把@之前的数量设置为6-11;
然后是@,在正则中,@还是字符,并无其他含义;
然后是后缀,是腾讯qq,还是网易163等,咋们把长度设置成2-6;
注意, 这里不能直接用. 而是用 \\. ,因为点(.)匹配除换行符意外的任意字符;
最后就是com / com.cn
好了,分析完之后,我们用代码来实现
Scanner email = new Scanner(System.in);
while (true){
System.out.print("请输入您的邮箱: ");
String isEmail = email.next();
if (isEmail.matches("\\w{6,11}@\\w{2,6}\\.(com|com\\.cn)")){
System.out.println("您输入的邮箱正确.");
break;
}else {
System.out.print("您输入的邮箱有误, ");
}
}
//结果
请输入您的邮箱: 1365@163.com
您输入的邮箱有误, 请输入您的邮箱: 1362462939@qq.com
您输入的邮箱正确.
Tips:
正则还有知识点,博主还未总结完,后期面加.