正则表达式
正则表达式的定义
正则表达式:符合一定规则的字符串表达式。
- |–作用:用于专门操作字符串。
- |–特点:用一些特定的符号来表示一些代码操作,简化书写。所以学习正则表达式,就是在学习一些特殊符号的使用。
- |–好处:简化对字符串的复杂操作。
- |–弊端:符号定义越多,正则表达式越长,阅读性差。
正则表达式对比实例
QQ号校验
需求:对用户输入的QQ号进行校验。
要求:5~15位,0不能开头,只能包含数字不能包含其他字符。
我们可以使用String类中封装的方法,组合各个函数来分别对三个要求进行判断,
例如:checkQQ_str()函数,但是处理时的组合代码较为复杂和繁琐。
public static void checkQQ_str(String QQ)
{
if(QQ.length()>=5 && QQ.length()<=15)
{
if(!(QQ.startsWith("0")))
{
try
{
Long lon = Long.parseLong(QQ);
System.out.println("QQ:"+QQ+" 合法.");
}
catch (NumberFormatException e)
{
System.out.println("QQ号中不能包含非数字字符!");
}
}
else
{
System.out.println("QQ号不能以0开头!");
}
}
else
{
System.out.println("QQ号长度不正确!");
}
}
使用正则表达式非常的简单和直观。
String类中的 boolean matches(String regex)函数 是用来判断一个字符串是否满足(匹配)某一正则表达式regex,满足返回true,否则返回false.
对于上述3个要求可以解读为:
- |–[1-9]:QQ号第一位只能是1-9中的数字.
- |–[0-9]{4,14}:第二位开始可以使0-9中的数字,并可以出现4到14次。
因此对应的正则表达式为:
String regex = “[1-9][0-9]{4,14}”;
于是我们可以使用checkQQ_reg()函数来实现。
非常的简单方便,这就是正则表达式的威力!!!
public static void checkQQ_reg(String QQ)
{
String regex = "[1-9][0-9]{4,14}";
boolean flag = QQ.matches(regex);
if(flag)
System.out.println("QQ:"+QQ+" 合法.");
else
System.out.println("QQ号格式错误,请重新输入!!!");
}
规则总结
字符类
[]:判断一个字符是否满足某条件,一个中括号表示一个字符。
|--枚举:(将满足的元素枚举出来)
[acg]:该字符只能是a或c或g。
|--区间:- (每个连续的区间使用-表示,并将满足的区间全部枚举出来)
[a-zA-Z]:a到z之间的字符,或A到Z之间的字符。
[a-d4-9]:a到d之间的字符,或4到9之间的数字。
|--与:&& (交集)
[a-z&&[def]]:在a到z之间,且是d,e,f中的字符,即d或e或f。
|--或:内部[] (并集),可以不添加,添加方便阅读。
[a-d[m-p]]:a到d或m到p之间的字符。
|--非:^ (不包含)
[^abc]:任意除了a,b,c的字符。
预定义字符类
|–注意:包含反斜杠()的预定义字符,由于在java中反斜杠表示转义字符,
所以需要使用两个反斜杠(\)来表示反斜杠,所以在正则表达式中,\是成对
出现的。
. 任意字符
\d 数字 [0-9]
\D 非数字 [^0-9]
\s 空白字符 [\t\n\xOB\f\r]
\S 非空白字符 [^\s]
\w 单词字符 [a-zA-Z_0-9] 字母数字或下划线
\W 非单词字符 [^\w]
数量词
X表示某一规则(以下正反例都已被验证)
X? X满足0次或1次,即最多一次。
例如:[a-zA-Z]\\d? 某个字母后面有0个或1个数字。
正例:b,b3
反例:b12
X* X满足0次或多次
例如:[a-zA-Z]\\d* 某个字母后面有任意个数字。
正例:b,b3,b33,b333
反例:b33a
X+ X满足1次或多次
例如:[a-zA-Z]\\d+ 某个字母后面至少有1个数字。
正例:b3,b33,b333
反例:b
X{n} X恰好满足n次
例如:[a-zA-Z]\\d{2} 某个字母后面有2个数字。
正例:b33
反例:b,b3,b333
X{n,} X至少满足n次
例如:[a-zA-Z]\\d{2,} 某个字母后面至少有2个数字。
正例:b33,b333,b3333
反例:b,b3
X{n,m} X至少满足n次,至多满足m次
例如:[a-zA-Z]\\d{2,4} 某个字母后面有2到4个数字。
正例:b33,b333,b3333
反例:b,b3,b33333
按照操作字符串的功能来分类讲解正则表达式的使用规则。
功能1:字符串匹配
使用String类中的 boolean matches(String regex)方法,用来判断一个字符串是否满足(匹配)某一正则表达式regex,
满足返回true,否则返回false.
例子2:
需求:匹配手机号,只有13xxx 15xxx 18xxx
分析:
手机号第一位只能是1,第二位可以是3或5或8,后面是任意9个数字。
所以正则表达式为: String telReg = “1[358]\d{9}”;
public static void checkTel()
{
String tel = "";
String telReg = "1[358]\\d{9}"
System.out.println(tel.matches(telReg));
}
功能2:字符串切割
使用String类中的 String[] split(String regex)方法,根据给定正则表达式来拆分字符串。
我们使用下面的函数来演示正则表达式的切割功能,通过修改参数str 和 regex的值来演示不同的效果。
public static void splitDemo(String str, String regex)
{
String[] arr = str.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}
例子3:
需求:将str中的人名切割出来
str = "zhangsan lisi wangwu";
regex = " ";//使用空格进行切割
运行结果:
zhangsan
lisi
wangwu
例子4:
需求:将str中的人名切割出来
str = "zhangsan lisi wangwu";
regex = " +";//使用一个或多个空格进行切割
运行结果:
zhangsan
lisi
wangwu
例子5:
需求:将str中的人名切割出来
str = "zhangsan.lisi.wangwu";
regex = "\\.";//.在正则表达式中表示任意字符,所以使用时需要转义。
运行结果:
zhangsan
lisi
wangwu
例子6:
需求:将str用\\切割出来
str = "c:\\abc\\a.txt";
regex = "\\\\";//两个反斜杠代表一个反斜杠。
运行结果:
c:
abc
a.txt
组的概念:
正则表达式中,为了可以让规则的结果被重用,
可以将规则封装成一个组,用()完成。
每个组都有自己的标号,从1开始(按照左括号出现的顺序编号)。
想要使用已有的组,可以通过\i的方式来获取,以便重复使用。
例子7:
需求:使用叠词来分割字符串。
分析:叠层表示,一个字符连续重复出现两次,即第一个字符是任意的,第二个字符和第一个相同。
因此我们可以使用 (.)\1 来表示,
str = "erkktyqquizzo";
regex = "(.)\\1";//按照叠层进行切割,任意字符连续出现两次。
运行结果:
er
ty
ui
o
例子8:
需求:使用叠词(2次或以上)来分割字符串。
str = "erkktyqqquizzzzzo";
regex = "(.)\\1+";//按照多叠词(2次或以上)进行切割,任意字符连续出现两次。
运行结果:
er
ty
ui
o
功能3:替换字符串
使用String类中的 String replaceAll(String regex, String replacement)
使用给定的replacement替换此字符串所有匹配给定正则表达式的子串。
使用下列函数来举例验证,正则表达式的替换功能。,通过修改参数str,regex和replacement的值来演示不同的效果。
public static void replaceAllDemo(String str, String regex, String replacement)
{
str = str.replaceAll(regex,replacement);
System.out.println(str);
}
例子9:
需求:将字符串中的长度大于等于5的数字串替换为#。
str = "wel121212121ty8722872fvg";
regex = "\\d{5,}";
replacement = "#";
运行结果:
wel#ty#fvg
例子10:
需求:将叠词替换为#。
str = "erkktyqqquizzzzzo";
regex = "(.)\\1";
replacement = "&";
运行结果:
er#ty#qui##zo
例子11:
需求:将叠词(2次及以上)替换为#。
str = "erkktyqqquizzzzzo";
regex = "(.)\\1+";
replacement = "&";
运行结果:
er#ty#ui#o
例子12:
需求:将str中重叠的字符替换成单个字母,即zzzz->z。
分析:在使用替换功能时,在replacement中我们可以使用$符号来获取regex中的组。
regex = "(.)\\1+" 中(.)表示重复的字符,我们在replacement中使用$1来获取。
str = "erkktyqqquizzzzzo";
regex = "(.)\\1+";
replacement = "$1";
运行结果:
erktyquizo
功能4:获取
将字符串中符合规则的子串获取出来。
操作流程:
- 将正则表达式封装成对象。
- 让正则对象和要作用的字符串相关联,获取匹配器对象(引擎)。
- 使用引擎对字符串进行操作,例如:获取,匹配,分割。。
其实前面的匹配,分割,替换等操作其实也是上述流程原理,只是被
封装成了方法。
例子13:
需求:在句子中获取由3个字母组成的单词。
其中 \b 代表单词边界符。
public static void getDemo()
{
String str = "ming tian jiu yao fang jia le, da jia.";
String regex = "\\b[a-z]{4}\\b";
//1将正则表达式封装成对象。
Pattern p = Pattern.compile(regex);
//2让正则对象和要作用的字符串相关联,获取匹配器对象(引擎)。
Matcher m = p.matcher(str);
//3使用引擎对字符串进行操作,例如:获取,匹配,分割。。
while(m.find())
{
System.out.println(m.start()+"..."+m.end());
System.out.println(m.group());
}
}
测试代码
import java.util.regex.*;
class RegexDemo
{
public static void main(String[] args)
{
/*
//匹配
checkQQ_str("0122134");
checkQQ_reg("12345678");
demo();
//切割
splitDemo("zhangsan lisi wangwu"," ");
splitDemo("zhangsan lisi wangwu"," +");
splitDemo("zhangsan lisi wangwu"," +");
splitDemo("zhangsan.lisi.wangwu","\\.");
splitDemo("c:\\abc\\a.txt","\\\\");
splitDemo("erkktyqquizzo","(.)\\1");
//替换
String str = "wel121212121ty8722872fvg";
replaceAllDemo(str,"\\d{5,}","#");
String str1 = "erkktyqqquizzzzzo";
replaceAllDemo(str1,"(.)\\1","#");
String str2 = "erkktyqqquizzzzzo";
replaceAllDemo(str2,"(.)\\1+","#");
String str3 = "erkktyqqquizzzzzo";
replaceAllDemo(str3,"(.)\\1+","$1");
*/
//获取
getDemo();
}
public static void getDemo()
{
String str = "ming tian jiu yao fang jia le, da jia.";
String regex = "\\b[a-z]{4}\\b";
//1将正则表达式封装成对象。
Pattern p = Pattern.compile(regex);
//2让正则对象和要作用的字符串相关联,获取匹配器对象(引擎)。
Matcher m = p.matcher(str);
//3使用引擎对字符串进行操作,例如:获取,匹配,分割。。
while(m.find())
{
System.out.println(m.start()+"..."+m.end());
System.out.println(m.group());
}
}
public static void replaceAllDemo(String str, String regex, String replacement)
{
str = str.replaceAll(regex,replacement);
System.out.println(str);
}
public static void splitDemo(String str, String regex)
{
String[] arr = str.split(regex);
for(String s : arr)
{
System.out.println(s);
}
}
public static void demo()
{
String s = "b3333";
String regex = "[a-zA-Z]\\d+";
boolean f = s.matches(regex);
System.out.println(f);
}
public static void checkQQ_str(String QQ)
{
if(QQ.length()>=5 && QQ.length()<=15)
{
if(!(QQ.startsWith("0")))
{
try
{
Long lon = Long.parseLong(QQ);
System.out.println("QQ:"+QQ+" 合法.");
}
catch (NumberFormatException e)
{
System.out.println("QQ号中不能包含非数字字符!");
}
}
else
{
System.out.println("QQ号不能以0开头!");
}
}
else
{
System.out.println("QQ号长度不正确!");
}
}
public static void checkQQ_reg(String QQ)
{
String regex = "[1-9][0-9]{4,14}";
boolean flag = QQ.matches(regex);
if(flag)
System.out.println("QQ:"+QQ+" 合法.");
else
System.out.println("QQ号格式错误,请重新输入!!!");
}
}