正则表达式
一、概述
1、概念:符合一定规则的表达式。
2、作用:用于专门操作字符串。
3、特点:用于一些特定的符号来表示一些代码操作,这样可以简化书写。所以学习正则表达式,就是在学习一些特殊符号的使用。
4、好处:可以简化对字符串的复杂操作。
5、弊端:符合定义越多,正则越长,阅读性越差。
二、常见符号
说明:X表示字符X或者匹配的规则。
1、字符
x 字符 x
\ 反斜线字符
\t 制表符 (‘\u0009’)
\n 新行(换行)符 (‘\u000A’)
\r 回车符 (‘\u000D’)
\f 换页符 (‘\u000C’)
\a 报警 (bell) 符 (‘\u0007’) 2、字符类
[abc] a、b或 c(简单类)
[^abc] 任何字符,除了 a、b或 c(否定)
[a-zA-Z] a到 z或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a到 d或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e或 f(交集)
[a-z&&[^bc]] a到 z,除了 b和 c:[ad-z](减去)
[a-z&&[^m-p]] a到 z,而非 m到 p:[a-lq-z](减去) 3、预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]4、边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾 5、Greedy数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n次
X{n,} X,至少 n次
X{n,m} X,至少 n次,但是不超过 m 次 6、组和捕获
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
组零始终代表整个表达式。在替换中常用$匹配组的内容。
三、正则表达式具体功能
主要有四种具体功能:匹配、切割、替换和获取
1、匹配:String类中的booleanmatches(String regex)方法。用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false。
示例:
package zhengex;
//正则表达式
public class RegexDemo {
public static void main(String[] args) {
String str="aooooooob";
String regex="ao{4,6}b";
boolean b=str.matches(regex);
System.out.println(str+":"+b);
}
}
package zhengex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//正则表达式用法,匹配,切割,替换,获取
public class RegexDemo2 {
public static void main(String[] args) {
//function_1();
//function_2();
//function_3();
function_4();
}
//匹配功能
public static void function_1(){
//校验手机号
String str="18863562901";
String regex="1[358]\\d{9}";//定义规则
boolean b=str.matches(regex);
System.out.println(str+":"+b);
}
//切割功能
public static void function_2(){
String str="zhangsanmmmmmlisitttttttwangwu";
String[] names=str.split("(.)\\1+");
for (String name : names) {
System.out.println(name);
}
}
//替换功能
public static void function_3(){
String str1="zhangsanmmmmmlisitttttttwangwu";
String str2=str1.replaceAll("(.)\\1+", "$1");
System.out.println(str2);
//替换手机号
String str="18863562901";//188****2901
String tel=str.replaceAll("(\\d{3})(\\d{4})(\\d{4})", "$1****$3");
System.out.println(tel);
}
//获取功能
public static void function_4(){
//获取字符串字母为三个的单词
String str="da jia hao,ming tian bu fang jia";
String regex="\\b[a-z]{3}\\b";
//将规则封装成对象
Pattern p=Pattern.compile(regex);
//将字符创封装成Matcher对象
Matcher m=p.matcher(str);
//获取单词,先find(),再group()
System.out.println(str);
while (m.find()) {
System.out.println(m.group());
System.out.println(m.start()+"-"+m.end());//获取单词的位置
}
}
}
练习:
package zhengex;
import java.util.TreeSet;
public class RegexTest {
public static void main(String[] args) {
/*
* 1、治疗口吃
* 2、IP地址排序
* 3、对邮件地址校验
*/
// test_1();
// test_2();
test_3();
}
//治疗口吃
public static void test_1(){
String str="我我...要要要要要要....学学学学学学....编编编编编编...程程程程程程";
String regex="\\.+";//先去掉.
str=str.replaceAll(regex, "");
System.out.println(str);
str=str.replaceAll("(.)\\1+", "$1");
System.out.println(str);
}
//ip地址排序
public static void test_2(){
String ip_str="192.168.10.34 127.0.0.0 3.3.3.3 105.70.11.55";
//为了能让他们按照字符串比较,前面补零成相同的位数
ip_str=ip_str.replaceAll("(\\d+)", "00$1");
//变为相同的位数
ip_str=ip_str.replaceAll("0*(\\d{3})", "$1");
String[] ip_arr=ip_str.split(" +");
TreeSet<String> ts=new TreeSet<String>();
for (String ip : ip_arr) {
ts.add(ip);
}
for (String ip : ts) {
System.out.println(ip.replaceAll("0*(\\d+)", "$1"));
}
}
//邮箱地址校验
public static void test_3(){
String mail="abc1@sina.com.cn";
String regex="[a-zA-Z0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{1,3})+";
boolean b=mail.matches(regex);
System.out.println(mail+":"+b);
}
}