正则表达式:正则表达式是用于操作字符串的一些规则,使用一些特殊的符号代表了字符串的规则。
用处:可用于对一些字符串校正
预定义字符类
. 任何字符(\.是用于匹配.的)
\d 数字:0-9
\D 非数字: ^0-9
\s 空白字符: \t\n\x0B\f\r空格
\S 非空白字符:^\s
\w 单词字符:a-zA-Z_0-9 a-z A-Z 0-9 _
\W 非单词字符:^\w
其实可以看出规律:大写就相当于比小写多了个“非”
注意: 一个预定于字符只能匹配一个字符,除非预定义字符串配合了数量词使用
范围词:[]里写的就是范围
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a-z或A-Z 两头的字母包括在内(范围)
[a-zA-Z0-9_] a-z或A-Z或0-9或_
注意:一个范围词没有配合数量词使用也只能匹配一个字符。
数量词:(X代表上面的预定义字符类)
X? X, 零次或一次
X* X, 零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
常见操作一:匹配 matches():
需求: 校验一个QQ号码。
1. 首位不能为0;
2. 长度: 5~ 12.
3. 全部是数字组成。
String qq = "1245124";
System.out.println(qq.matches("[1-9]\\d{4,11}")?"合法QQ":"非法QQ");
qq.matches("[1-9]\\d{4,11}") 就是通过调用matches方法看其是否符合正则表达式。
可以看以下代码让自己多加熟悉。注意:\\中有一\是表示转义两根\相当于一根\
System.out.println(". 任何字符:"+("%".matches("."))); //true
System.out.println("\\d代表了数字:"+("a".matches("\\d"))); //true
System.out.println("\\D代表了非数字:"+("@".matches("\\D"))); //true
System.out.println("\\s代表了空白字符:"+("\n".matches("\\s"))); //true
System.out.println("\\S代表了非空白字符:"+("a".matches("\\S"))); //true
System.out.println("\\w代表了单词字符:"+("_".matches("\\w"))); //true
System.out.println("\\W代表了非单词字符:"+("a".matches("\\W"))); //false
注意: 一个预定于字符只能匹配一个字符,除非预定义字符串配合了数量词使用。
System.out.println("\\d代表了数字:"+("12".matches("\\d"))); //false
System.out.println("?一次或一次也没有:"+ ("12".matches("\\d?")));
System.out.println("* 零次或多次:"+ ("12".matches("\\d*")));
System.out.println("* 零次或多次:"+ ("abc".matches("\\d*")));//前面与d匹配虽然是0次,但后面abc没东西与其匹配,返回的是false
System.out.println("+ 至少一次:"+ ("12".matches("\\d+")));
System.out.println("{n} 恰好n次:"+ ("121".matches("\\d{3}")));
System.out.println("{n,} 至少出现n次:"+ ("121".matches("\\d{3,}")));
System.out.println("{n,m} 至少出现 n~ m次 :"+ ("1212111".matches("\\d{3,6}")));
注意:一个范围词没有配合数量词使用也只能匹配一个字符。
如: System.out.println("abc".matches("[abc]")); //false
System.out.println("d".matches("[abc]+"));
System.out.println("abc".matches("[^abc]+"));
System.out.println("123456_".matches("[a-zA-Z0-9_]+"));
常见操作二:切割 split()
public static void main(String[] args){
String str = "我 是 大 笨 猪";
String reg = " +"; //写一个正则表达式
String[] datas = str.split(reg);
for(int i = 0;i<datas.length;i++) {
System.out.print(datas[i]);
}//我是大笨猪
}
上面正则表达式:" +" 空格+中是属于预定义字符中的预定义字符 而+是数量词表示一个及以上 str.split(" +"); 则表示劈掉连在一起一个及一个以上的空格。
那如果我想要劈掉某个叠字是不是也可以用同样的方法?让我们试一下
public static void main(String[] args) {
String str = "我是大大大大大笨笨笨笨笨猪";
String reg = "大+";
String[] datas = str.split(reg);
for(int i = 0;i<datas.length;i++) {
System.out.print(datas[i]);
}//我是笨笨笨笨笨猪
}
看到输出结果,我们发现确实可以,但是如果我要劈掉所有的叠字呢?我们总不可能一个一个写劈每个字的正则然后一个个劈吧,那我们要怎么做呢?
public static void main(String[] args){
String str = "我是大大大大大笨笨笨笨笨猪";
String reg = "(.)\\1+"; //写一个正则表达式
String[] datas = str.split(reg);
for(int i = 0;i<datas.length;i++) {
System.out.print(datas[i]);
}//我是猪
}
通过上面的正则表达式成功把所有叠词给劈掉,那接下来让我们理解一下上面正则表达式。
首先先了解一些知识点
然后我们可以开干了……
通过上面的我想大家都知道劈掉所有的叠词字符了,那如果我们要把所有的叠字换成一个字又要怎么办呢?这就要用到下一个常用操作的方法了。
常用操作三:替换 replaceAll(String reg,String replacement);
操作方法其实很简单,先演示一波:
public static void main(String[] args) {
String str1 = "我是猪";
String reg = "我是猪";
String str2 = str1.replaceAll(reg,"你是猪");
System.out.println(str2);
}//你是猪
简直就是so easy!
那下面来操作一下怎么将上面的叠字换成一个字:
public static void main(String[] args) {
String str1 = "我是大大大大大笨笨笨笨笨猪";
String reg = "(.)\\1+";
String str2 = str1.replaceAll(reg,"$1");//引用正则的内容如果不是在一个正则表达式内部,
System.out.println(str2); //那么需要使用 :"$组号" 进行引用
}//我是大笨猪
这里还要知道的就是:如果引用正则的内容如果不是在一个正则表达式内部,那么就需要使用 "$组号" 进行引用。上面的$1就相当于第一组的内容,也就是(.)匹配到的内容。
常用操作四:查找这里需要用到两个类的实例对象,
Pattern(的正则对象)
Matcher(的匹配器对象)
其中Matcher的对象有两个非常常用的方法:
一、 find() 通知匹配器去查找符合该正则的字符串。如果存在符合规则的字符串返回true,否则返回false.
二、 group() 获取符合规则的字符串。
在这里需要注意的是: 使用匹配器的方法时候,要先调用find方法才能调用group方法。 否则匹配器没有去查找合适的内容没法去获取,就会报错。
通常的操作如下图红色框中部分:
先举个使用的例子方便大家理解,看完例子,你必能恍然大悟:
需求:获取文章中打广告的11位数电话号码,并把它获取出来。
public static void main(String[] args) {
String str1 = "要学习正则表达式请联系:12223334445,机不可失失不再来,请记住:12223334445";
String reg = "1[0-9]{10}";//以1开头,后面的字符内容是0-9且0-9字符的个数恰好是10个(正则表达式就是表示以1开头的11位数号码)
Pattern p = Pattern.compile(reg);//把字符串的正则编译成Pattern对象
Matcher m = p.matcher(str1);//使用正则对象去匹配字符串,得到一个matcher对象
if(m.find()) {
System.out.println(m.group());
}
}//12223334445
像这样就可以抓取出我们想要的东西了(其实这可以应用到网页爬虫中去)
但想上面这样其实还有一点小问题,看下面例子:
public static void main(String[] args) {
String str1 = "一串数字:1222333444555666777888";
String reg = "1[0-9]{10}";//以1开头,后面的字符内容是0-9且0-9字符的个数恰好是10个(正则表达式就是表示以1开头的11位数)
Pattern p = Pattern.compile(reg);//把字符串的正则编译成Pattern对象
Matcher m = p.matcher(str1);//使用正则对象去匹配字符串,得到一个matcher对象
if(m.find()) {
System.out.println(m.group());
}
}//12223334445
像这样抓出的也是个以1开头的11位数,但实际上却并不是我们想要的电话号码。这里要解决就必须还要知道一个东西:边界匹配 \b
正则表达式中,可以在字符 前加“\b”,来匹配其后面的字符位于字符串首位的字符 正则表达式中,可以在字符 后加“\b”,来匹配其前面的字符位于字符串末位的字符
有了它问题就可以解决了:
public static void main(String[] args) {
String str1 = "一串数字:1222333444555666777888";
String reg = "\\b1[0-9]{10}\\b";//以1开头,后面的字符内容是0-9且0-9字符的个数恰好是10个(正则表达式就是表示以1开头的11位数)
Pattern p = Pattern.compile(reg);//把字符串的正则编译成Pattern对象
Matcher m = p.matcher(str1);//使用正则对象去匹配字符串,得到一个matcher对象
if(m.find()) {
System.out.println(m.group());
}
}//
以上是正则表达式常用内容,希望大家有所收获!
若有不明白的地方欢迎评论区留言
码字不易,不希望白嫖,如果觉得有所收获请给博主点赞收藏支持一波吧!