一、简介
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。在众多语言中都可以支持正则表达式,如Perl、PHP、Java、Python、Ruby等。当然在Java中也可以通过处理字符串的方式达到检索,替换文本字符串的目的,但是有了正则表达式写代码更加简洁,通常两三行代码就可以达到目的,当然这也是建立在熟悉正则表达式的基础之上的。简单来说,正则表达式就是用字符串来描述规则,并用来匹配字符串的机制。
而在我们的Java中,Java内置正则表达式的引擎java.util.regex内。在实现正则表达式主要是依靠由java.util.regex的Pattern和Matcher类实现的。使用这两个类可以实现对我们的字符串进行样式匹配。这样我们就减少了很多的代码量,而且简便快捷。
二、引子
简单的举个栗子,假如我们现在要去简单的判断输入的字符串是否为电话号码,按照我们原始的Java实现就是:先判断它的长度是不是11位。然后判断是否为0-9的数字。
代码实现:
//判断输入是否为电话号码
static boolean isPhoneNumber(String str){
//长度判断
if (str.length() != 11){
return false;
}
//值判断
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c< '0' ||c >'9'){
return false;
}
}
return true;
}
当我们使用正则表达式之后
public static boolean isPhone(String year){
return year.matches("\\d{3,4}\\-1\\d{10}");
}
二者简单对比…………当然我们在使用判断是否为Email、是否为日期时,会不禁感慨:真香。。。
三、匹配规则
Java的正则表达式和JS的正则表达式都是差不多的,都是从左向右依次进行匹配,当存在特殊字符串时,也要用“ \d ”来进行转义
-
方括号[ ]:表示匹配括号中的所有元素, var a=/[a~z]/ 表示匹配a~z的字符串
-
花括号{ }:表示匹配多少个字符,与方括号一起使用 var a=/[a~z]{3}/ 表示匹配连续3个a~z的字符串;var a=/[a~z]{2,3}/ 花括号内表示满足区间[2,3]的数
-
小括号( ):表示提取字符串
-
当表示匹配一个字符串开头 var a=/ ^ [a-z] / 表示以小写字母开头; 当^符号出现在[ ]里面第一的位置,表示不包含此字符串 var a=/ [^a] / 表示不能有a
-
$ 符号:表示匹配一个字符串的结尾 var a=/d$/ 表示以d 结尾
-
转义字符
-
量词
量词 | 描述 |
---|---|
{ n } | 表示匹配的个数 |
{n,m} | 匹配一个n-m 个字符 |
{n, } | 匹配至少n 个字符 |
[……] | 匹配 范围内的字符,仅匹配一个 例:[abcd]、[a-d] |
[^……】 | 匹配非范围内的字符 |
四、贪婪匹配
在Java 的正则表达式中,是默认执行贪婪表达式的。
什么是贪婪匹配?
例:当我们要给定一串字符串,要来判断该字符串的末尾 0 的个数时,比如“12300000”,我们使用正则表达式匹配大致思路时,给定的匹配规则为:“(^\d+) (0*)”。 然后我们期望的结果是
input | \d+ | 0* |
---|---|---|
12300000 | “123” | “00000” |
但是在我们实际运行中发现,我们的得到的结果是
input | \d+ | 0* |
---|---|---|
12300000 | “12300000” | " " |
这样我们其实发现,我们运行出来的结果也是没有错误的。这里就是它在运行时,默认使用了贪婪匹配,也就是尽可能多的向后匹配。在此例子中,我们在使用“\d+” 的时候,会尽可能的向后匹配多的数字,这样导致“0*” 匹配到的字符串为空。
如何避免?
我们使用“?”来实现非贪婪匹配。所以我们的“?”既可以表示0个或1个字符串,也表示非贪婪匹配
这样我们在代码中实现就是:
Pattern pattern=Pattern.compile("^(\\d+?)(0*)$");
Matcher matcher = pattern.matcher("12560000");
if (matcher.matches()){
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
}
得到的结果便是:
五、搜索和替换
我们可以根据String类,来结合匹配机制,可以对其进行简单的搜索、替换和分割。
1.分割—split()
我们使用split() 方法可以对我们的匹配字符串进行分割。例如
String tar="java python php Android JS";
String[] split = tar.split("\\s");
System.out.println(Arrays.toString(split));
我们开一下结果
2.搜索—find()
根据find() 方法可以从我们的字符串的中,查找是否包含你所要查询的字符串,返回值为true或false
String sta="the name is vary good.";
Pattern p=Pattern.compile("the");
Matcher m=p.matcher(sta);
while (m.find()){
String s = sta.substring(m.start(), m.end());
System.out.println(s);
}
结果:
3.替换—replaceAll()
我们使用replaceAll()方法可以调整我们的输入样式
String str="I have an apple,but I don't want to you";
System.out.println(str); //输入前,样式不规范,有的含有多个空格
String s = str.replaceAll("\\s+", " ");
System.out.println(s); //输入后
结果: