在了解正则表达式之前我们先用已学知识完成一段代码
需求:校验QQ号是否正确(QQ号格式:由5-11位数字组成 ,第一位数字不能是0)
public class Demo {
public static void main(String[] args) {
//定义一个错误的QQ号
String qq = "0174896990";
//校验qq号
boolean flag = checkQQ(qq);
System.out.println(flag);
}
private static boolean checkQQ(String qq) {
char start = qq.charAt(0);
if(start == '0'){
return false;
}
int len = qq.length();
//qq号的长度位5-11位
if(len < 5 || len >11){
return false;
}
//必须全部是数字
for (int i = 0; i < qq.length(); i++) {
char c = qq.charAt(i);
if(c < '0' || c >'9'){
return false;
}
}
return true;
}
}
运行结果:
false
可以看出此代码校验QQ号过于繁琐,而正则表达式的出现可以简化代码
public class Test {
public static void main(String[] args) {
String qq = "2678793456";
//正则表达式
//[1-9]:表示第一个数不能是0
// \\d:表示全部是数字
//{4,10}:表示还剩4-10个数字
String regex = "[1-9]\\d{4,10}";
System.out.println(qq.matches(regex));
}
}
运行结果:
这里就是正则表达式的用法
正则表达式
介绍:
正则表达式是按照某种规则去匹配符合条件的字符串
作用:
把异常数据进行过滤,校验
字符类:(只匹配一个字符)
字符 | 含义 |
[abc] | 只能是a,b或c |
[^abc] | 除了a,b,c之外的任何字符 |
[a-zA-Z] | a-z A-Z包含在内 |
[a-d[m-p]] | a到d ,或m到p(和上一个差不多,便于阅读) |
[a-z]&&[def] | a-z和def的交集 为:def |
[a-z&&[^bc]] | a-z和非bc的交集 |
[a-z&&[^b-e]] | a-z和非b-e的交集 |
以下代码示例:
public class Demo2 {
public static void main(String[] args) {
//正则表达式
//字符类(只匹配一个字符)
// [abc] 只能是a,b,或c
System.out.println("a".matches("[abc]"));//true
System.out.println("ab".matches("[abc]"));//false
System.out.println("0".matches("[abc]"));//false
//[^abc] 除了a,b,c之外的任何字符
System.out.println("a".matches("[^abc]"));//false
System.out.println("d".matches("[^abc]"));//true
System.out.println("0".matches("[^abc]"));//true
//[a-zA-Z] a到z A到Z,包含范围
System.out.println("a".matches("[a-zA-Z]"));//true
System.out.println("0".matches("[a-zA-Z]"));//true
System.out.println("ac".matches("[a-zA-Z]"));//false
System.out.println("ac".matches("[a-zA-Z][a-zA-Z]"));//true
//[a-d[m-p] a到d,或m到p 和上面的差不多,便于阅读
System.out.println("a".matches("[a-d[m-p]]"));
//[a-z]&&[def] a-z 和def的交集 为:d,e,f
System.out.println("a".matches("[a-z]&&[def]"));//false
//细节:如果要求两个范围的交集,那么写符号&&
//如果携程一个&,那么此时的&就不是交集了,只是一个简单的&符号
//这里表示 a-z 或& 或def
System.out.println("a".matches("a-z&[def]"));//true
//[a-z&&[^bc]] 表示a-z与非bc的交集
System.out.println("a".matches("[a-z&&[^bc]]"));//true
//[a-z&&[^m-p]] a到z和除了m到p的交集
System.out.println("a".matches("[a-z&&[^m-p]]"));//true
}
}
预定义字符:(只匹配一个字符)
字符 | 含义 |
. | 任意字符 |
\d | 0~9之间的其中一个 |
\D | 非数字,相当于[^0-9] |
\s | 空白字符(\t \n 等) |
\S | 非空白字符,相当于[^\s] |
\w | 单词字符:[a-zA-Z_0-9],大小写英语字母、下划线、数字 |
\W | 非单词字符,相当于[^\w] |
在代码演示前先插入一个练习
要求:以字符串的形式打印一个双引号
如按照这种输出方式,运行时则会出错
这时我们需要在 " 前添加转义字 \
// \ 转义字符 改变后面那么字符原本的含义 System.out.println("\""); //" 在Java中表示字符串的开头或者结尾 //此时\表示转移字符,改变了后面那个双引号原本的含义 //把他变成 了一个普通的"
以下代码示例:
public class Demo3 {
public static void main(String[] args) {
//. 表示任意字符
System.out.println("a".matches("."));//true
System.out.println("aa".matches("."));//false
System.out.println("aa".matches(".."));//true
// \\d表示任意一个数字
// \\d只能是任意的以为数字
// 简单来记:两个\\表示一个\
System.out.println("1".matches("\\d"));//true
System.out.println("g".matches("\\d"));//false
// \D非数字
// \w 英文 数字、下划线
System.out.println("a".matches("\\w"));//true
//必须是数字,字母,下划线 至少六位
System.out.println("abcder".matches("\\w{6,}"));//true
//必须是数字,字母,下划线 必须4位
System.out.println("abcd".matches("\\w{4}"));//true
//必须是数字,字母,下划线 6~10位
System.out.println("aggdgetev".matches("\\w{6,10}"));//true
}
}
上面
{6,}表示 单词字符至少出现6次
{4}表示单词字符只能出现4次
{4,10}表示单词字符可以出现4到10次
数量词:
字符 | 含义 |
? | 0次或1次 |
* | 0次或多次 |
+ | 1次或多次 |
{n} | 出现n次 |
{n,} | 至少n次 |
{n,m} | n到m次 |
练习1:
请编写正则表达式验证用户输入的手机号码是否满足要求
//拿出一个正确的数据,从左向右一次去写
//19239336784
//分成三部分
//第一部分:1 表示手机号码以1开头
//第二部分:[3-9] 表示手机号第二位数字只能是3-9之间的
//第三部分:\\d{9}表示任意数字可以出现9次,也只能出现9次
//先定义一个字符串
String regax1 = "1[3-9]\\d{9}";
System.out.println("19239336784".matches(regax1));
System.out.println("18935667894".matches(regax1));
System.out.println("13897883456".matches(regax1));
练习2:
请编写正则表达式验证24小时制时间是否满足要求
public class Demo4 {
public static void main(String[] args) {
//思路:
//先拿出一个二十四小时制时间 23:34:05
//将24小时制时间分为三部分
//第一部分:时
// 0~23小时 00~09 10~19 20~23 ([01][0-9])|(2[0-3]):
//解释:如果第一个数字是0或1,那么第二个数字就是0~9;
// 如果第一个数字是2,那么第二个数字就是0~3
//第二部分:分
// 00~59分 [0-5][0-9]:
//第三部分:秒
//第三部分和第二部是一样的
// 00~59分 00~59 [0-5][0-9]
//定义一个字符串,将上面的拼接起来,表示正则表达式
//以下两种方法都可以
// [0-9]等价于\d
String regex = "([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]";
String regex1 = "([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d";
//校验
System.out.println("23:34:05".matches(regex1));//true
System.out.println("10:47:59".matches(regex));//true
System.out.println("19:50:60".matches(regex));//false
//注意:|表示或,这里必须要用括号把[01][0-9]|2[0-3]括起来
}
}
此练习中思考中的第二部分和第三部分是一样的,可以把第二部分和第三部分看成一组,这一组出现两次,因为正则表达式可以改写为:
String regex2 = "([01]\\d|2[0-3])(:[0-5]\\d){2}";
练习3:
请编写正则表达式验证身份证号码是否满足要求(身份证号共18位,前17位任意数字,最后一位可以是数字可以是大写或小写的X)
public class Demo5 {
public static void main(String[] args) {
//验证身份证
//347892200504063689 34689078900205342x 34178903456789324X
//String regax2 = "\\d{17}[0-9xX]";
//身份证号码第一个数不能为0
//三种方法都可以
String regax2 = "[1-9]\\d{16}[0-9xX]";
String regax3 = "[1-9]\\d{16}(\\d|x|X)";
String regax4 = "[1-9]\\d{16}[\\dxX]";
System.out.println("347892200504063689".matches(regax2));
System.out.println("34689078900205342x".matches(regax2));
System.out.println("34178903456789324X".matches(regax2));
}
}
在Java的正则表达式中我们可以使用(?i)标识符来进行忽略字母大小写的匹配
代码如下:
public class Demo6 {
public static void main(String[] args) {
String regex = "(?i)apple";
//此时忽略了apple的大小写
System.out.println("APPLE".matches(regex));//true
//实现只忽略A的大小写
String regex1 = "((?i)a)pple";
System.out.println("Apple".matches(regex1));//true
System.out.println("APPLE".matches(regex1));//false
System.out.println("aPPle".matches(regex1));//false
}
}
我们可以使用(?i)实现验证身份证最后一个x的大小写
String regax4 = "[1-9]\\d{16}[\\d(?i)x]";