------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
基础知识点
正则表达式
作用:用于专门操作字符串
本质:是一些特定的符号来表示一些代码的操作,其实底层肯定还是代码。
好处:简化了书写。
弊端:符号定义越多,正则越长,阅读性越差。
常用符号:
字符类
[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](减去)
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字: [0-9]
\D 非数字: [^0-9]
\s 空白字符: [ \t\n\x0B\f\r]
\S 非空白字符: [^\s]
\w 单词字符: [a-zA-Z_0-9]
\W 非单词字符: [^\w]
边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
组的封装和捕获
可以将规则封装成一个组。用()完成。组的出现都有编号,从1开始。
想要使用已有的组可以通过 \n(n就是组的编号)的形式来获取。
如:用叠词切割字符串
String line = "abadddddefdggdgdfffdegbd";
String regex = "(.)\\1+";
在表达式 ((A)(B(C))) 中,存在四个这样的组: 通过从左到右计算其开括号来编号
组1 ((A)(B(C)))
组2 \A
组3 (B(C))
组4 (C)
组零始终代表整个表达式。
组的引用:使用$n来引用组,一般用在替换操作中
替换:String replaceAll(regex,str);如果regex中有定义组,可以在第二参数中通过$符号
获取正则表达式中的已有的组。
如:把一个字符串中的叠词替换成一个字符
String line = "abadddddefdggdgdfffdegbd";
line.replaceAll("(.)\\1+","$1");即:用组1中的内容替换满足表达式规则的内容
1.匹配
String 类的mathes方法 public boolean matches(String regex)
用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false。
对QQ号码进行校验要求:5~15 0不能开头,只能是数字
String regex = "[1-9]\\d{4,14}";
匹配手机号段只有 13xxx 15xxx 18xxxx
String telReg = "1[358]\\d{9}";
2.截取
String类的split功能 public String[] split(String regex)
按照叠词完成切割
splitDemo("erkktyqqquizzzzzo","(.)\\1+");
按目录切割
splitDemo("c:\\abc\\a.txt","\\\\");
3.替换
String类的replaceAll功能 public String replaceAll(String regex,String str)
注意:此方法是得到了一个新的字符串,原字符串的内容并为发生变化。当然可以重新赋值给原串。
String replaceAll(regex,str);如果regex中有定义组,可以在第二参数中通过$符号
将叠词替换成#
replaceAll("(.)\\1+","#");
将叠词替换成单个字符
replaceAll("(.)\\1+","$1");
4.获取
如:获取一段字符串中符合规则的数据,获取3个字符的单词
String str = "ming tian jiu yao fang jia le ,da jia。";
String reg = "\\b[a-z]{3}\\b";
使用正则表达式的特有功能,步骤:
A:将正则表达式封装成对象
查看API可以发现正则表达式的描述是在Pattern类中,此类是正则表达式的编译表示形式
Pattern p = Pattern.compile(reg);
B:让正则对象和要操作的字符串相关联,获取匹配器对象
Matcher m = p.matcher(str);
C:通过匹配器对象的方法对符合规则的子串进行操作,如查找和获取
while(m.find()){
System.out.println(m.group());
System.out.println(m.start()+"...."+m.end());
}
其实String类的matches方法,用的就是Pattern和Matcher对象来完成的
只不过被String的方法封装后用起来较为简单,但是功能比较单一。
m.matches();//这里匹配的是符合规则的子串,如果是String的方法,匹配的这是整个字符串。
到底用四种功能中的哪一个呢?或者哪几个呢?
思路方式:
1,如果只想知道该字符是否对是错,使用匹配。
2,想要将已有的字符串变成另一个字符串,替换。
3,想要按照自定的方式将字符串变成多个字符串。切割。获取规则以外的子串。
4,想要拿到符合需求的字符串子串,获取。获取符合规则的子串。
拓展案例
/*
正则表达式的应用实例
1.处理"我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程"
2.192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30 将ip地址进行地址段顺序的排序。
*/
import java.util.Arrays;
class ReplaceDemo{
public static void main(String[] args){
//测试功能
strReg();
ipReg();
}
public static void strReg(){
//定义字符串
String line = "我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程";
/*
分析:
使用字符创的替换功能,先把...去掉,然后在把叠词替换为一个字符
*/
//把...替换为空
line=line.replaceAll("\\.+","");
//把叠词替换为一个字符
line=line.replaceAll("(.)\\1+","$1");
//输出结果
System.out.println(line);
}
public static void ipReg(){
//定义字符串
String line = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
/*
分析:
按地址段排序其实就是自然排序,但有点小问题
2.2.2.2肯定是在102.49....前面的,但直接排序肯定就排到后面去了
如果变成002.002....就好了
我们首先把位数最低的数变为3位数(用0补),然后再去掉多余的0,排序后再去掉首位的0
*/
//用0把数值补位
line = line.replaceAll("(\\d+)","00$1");
//把多余3位的数变为3位数
line = line.replaceAll("0*(\\d{3})","$1");
//用空格分隔数据
String[] strs = line.split(" ");
//利用数组的工具类排序
Arrays.sort(strs);
//排序后遍历数组并把首位的0去掉后输出
for(String s:strs){
System.out.println(s.replaceAll("0*(\\d+)","$1"));
}
}
}