一、正则表达式
正则表达式是一个强大的字符串处理工具,可以对字符串进行匹配、提取、分割、替换等操作,除此之外,java还专门提供了Pattern和Matcher两个类用于支持正则。正则表示式可以本质上使用一些字符代替复杂的代码操作,因此掌握良好的正则表达式只是能够简便我们对字符串的处理。
正则表达式中的特殊字符及其含义,烦请查看JAVA api开发文档(java.util.regex.Pattern)或者参看文章《java正则表达式详解》(链接:http://www.jb51.net/article/16829.htm)。
二、使用正则
正则表达式,首先要了解正则的规则,其次要多练习。使用正则,切记转义符号“\"一定是成对出现的。
- 匹配(matches)
匹配主要用来做字符串检验,判断字符串是否符合规则,而获取主要用于提取符合规则的字符串。
匹配QQ,代码示例如下,其中"[]"表示枚举,形如[abc]表示或a或b或c,形如[^abc]表示非a、b、c,\d表示数字,{n}表示出现n次,如果想表现至少n次则形如{n,},如果想表现出现n次到m次(包含n不包含m)则形如{n,m}。
package regx;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatchQQ {
public static void main(String[] args) {
/*
* 匹配QQ
* 1. 不能0开头;
* 2. 不能非数字;
* 3. 长度是15位;
*/
String qq1 = "0123456";
String qq2 = "12345679a";
String qq3 = "123456789101254";
Pattern p = Pattern.compile("[1-9]\\d{4, 14}");
Matcher matcher = p.matcher(qq1);
System.out.println(matcher.matches());
matcher = p.matcher(qq2);
System.out.println(matcher.matches());
matcher = p.matcher(qq3);
System.out.println(matcher.matches());
}
}
2. 匹配手机号
package regx;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatchQQ {
public static void main(String[] args) {
/*
* 匹配手机号
* 1. 号码长11位;
* 2. 只匹配13、15、18开头的号段
*/
String phoneNumber = "131519";
String phoneNumber2 = "12693078451";
Pattern p = Pattern.compile("1[358]\\d{9}");
Matcher matcher = p.matcher(phoneNumber);
System.out.println(matcher.matches());
matcher = p.matcher(phoneNumber2);
System.out.println(matcher.matches());
}
}
- 切割(split)
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 切割字符串
* 1. 遇到空格切割;
* 2. 遇到“+”切割;
*/
String str = "ab cd++eeff +g";
String regex = "[ +]{1,}";
String[] strs = str.split(regex);
for(String i:strs)
System.out.println(i);
}
}
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 切割字符串
* 1. 遇到“.”则切割
*/
String str = "a.cd+.+..eeff.+g";
String regex = "\\.";
String[] strs = str.split(regex);
for(String i:strs)
System.out.println(i);
}
}
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 切割目录
* 1. 遇到“\\”则切割
*/
String str = "D:\\demo\\okc";
String regex = "\\\\";
String[] strs = str.split(regex);
for(String i:strs)
System.out.println(i);
}
}
按照叠词进行切割,代码示例如下,其中"()"表示分组,如果有多个分组默认会从1开始编号,要想引用前面分组的内容,则使用"\n"即可,例如引用第一个分组的内容,则写成"\1","+"表示前面的内容出现一次或多次。
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 按照叠词进行切割
* 1. 遇到重复的字母进行切割,例如aa,bb
*/
String str = "abbcddeefgabdood";
String regex = "(.)\\1+";
String[] strs = str.split(regex);
for(String i:strs)
System.out.println(i);
}
}
- 替换(replace)
利用字符串的replaceAll方法进行替换,代码示例如下,其中"\d"表示数字,"\D"表示非数字。
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 将字符串中的一组数字替换成@
*/
String str = "ab1bc158dd1325de895efg1a0bd2ood";
String regex = "(\\d+)";
System.out.println(str.replaceAll(regex, "@"));
/*
* 输出结果:ab@bc@dd@de@efg@a@bd@ood
*/
}
}
“+”号表示出现一次或多次,上例中如果去掉regex中的加号,表示一个数字替换成一个@,输出结果如下。
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 将字符串中的数字替换成@
*/
String str = "ab1bc158dd1325de895efg1a0bd2ood";
String regex = "(\\d)";
System.out.println(str.replaceAll(regex, "@"));
/*
* 输出结果:ab@bc@@@dd@@@@de@@@efg@a@bd@ood
*/
}
}
将叠词替换成@,代码示例如下。
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 将一组叠词替换成@
*/
String str = "abccdeffffgaabookkmln";
String regex = "(.)\\1+";
System.out.println(str.replaceAll(regex, "@"));
/*
* 输出结果:ab@de@g@b@@mln
*/
}
}
将叠词替换成单个字符,代码示例如下,其中通过$1表示获取前一个规则中的第一组,$n表示前一个规则中的第n组。
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 将一组叠词缩减成一个字符,例如zzzz缩减成z
*/
String str = "abccdeffffgaabookkmln";
String regex = "(.)\\1+";
System.out.println(str.replaceAll(regex, "$1"));
/*
* 输出结果:abcdefgabokmln
*/
}
}
- 获取(find)
获取字符串中三个字母组成的单词,代码示例如下,其中"\b"表示单词边界。
package regx;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StrRegex {
public static void main(String[] args) {
/*
* 提取字符串中三个字母组成的单词
*/
String str = "an jing shi yi zhong xiu xing, ni ke zhi dao?";
Pattern p = Pattern.compile("\\b[\\w]{3}\\b");
Matcher matcher = p.matcher(str);
while(matcher.find()){
System.out.println(matcher.group());
}
/*
* 输出结果:abcdefgabokmln
*/
}
}
三、练习
package regx;
public class StrRegex {
public static void main(String[] args) {
/*
* 将下列字符串转换成“我要写代码”
*/
String str = "我我...要要...要写写写写..写代码..码码";
//1.先去掉“.”
str = str.replaceAll("(\\.)\\1+", "");//或者str = str.replaceAll("\\.+", "");
//2.接着进行叠词替换
str = str.replaceAll("(.)\\1+", "$1");
System.out.println(str);
}
}
package regx;
import java.util.Iterator;
import java.util.TreeSet;
public class StrRegex {
public static void main(String[] args) {
/*
* 将ip地址按照ip段进行排序
*/
String str = "192.168.0.5 193.168.5.1 10.10.10.1 2.2.2.3 8.9.4.7";
str = str.replaceAll("(\\d+)", "00$1");
System.out.println(str);
str = str.replaceAll("0*(\\d{3})", "$1");
System.out.println(str);
String[] strs = str.split(" +");
for(String i:strs)
System.out.println(i);
TreeSet<String> tSet = new TreeSet<>();
for(String i:strs)
tSet.add(i);
System.out.println("-------------");
for(Iterator<String> it=tSet.iterator(); it.hasNext(); ){
System.out.println(it.next().replaceAll("0*(\\d+)", "$1"));
}
/*输出结果:
2.2.2.3
8.9.4.7
10.10.10.1
192.168.0.5
193.168.5.1*/
}
}
package regx;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StrRegex {
public static void main(String[] args) {
/*
* 对邮件地址进行校验
*/
String regex = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
/*
* 1. \\w+:表示[a-zA-Z_0-9]开头一个或多个,QQ邮箱也可以校验
* 2. ([-+.]\\w+)*
* a. [-+.]:表示"-"或"+"或"."
* b. \\w+:表示[a-zA-Z_0-9]开头一个或多个
* c. ([-+.]\\w+):一个分组,该组里面是"-+."中的一个和一个或多个单词字符组成
* d. *:表示0个或多个
* e. ([-+.]\\w+)*:表示这个分组(该组里面是"-+."中的一个和一个或多个单词字符组成)出现0次或多次
* 3. @:必须包含一个@字符
* 4. \\.:必须包含一个"."
*/
String mail = "wxy51yes@outlook.com";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(mail);
System.out.println(m.matches());
}
}
附注:
本文如有错漏之处,烦请不吝指正,谢谢!