获取:我想把符合规则的字符串取出来
match:是判断字符串是否符合规则.返回真假
replace:是返回替换后的
切割:把规则以外的结果取出来
操作规则:
- 将正则表达式封装成对象
- 让正则对象和要操作的字符串相关联
- 关联后,获取正则匹配引擎
- 通过引擎对符合规则的子串进行操作,比如取出.
package zhengze;
import java.util.regex.*;
public class str {
public static void main(String[] args) {
getDemo();
}
public static void getDemo(){
String str = "ming tian jiu yao fang jia le ,wo men"; //将被提取的源字符串
String reg = "[a-z]{3}";
//---------------------------1
/*
* 将规则封装成对象
* */
Pattern p = Pattern.compile(reg);
//-----------------------------------------2
/*
* 让正则对象和要作用的字符串相关联.获取匹配器对象Matcher
* 有了匹配器对象之后,可以利用匹配器对象对字符串来进行多种操作
* */
Matcher m = p.matcher(str);
//-------------------------------------3
/*
* 将规则作用到字符串上,并进行符合规定的子串查找
* */
Boolean IsFind = m.find(); //查看有没有按照正则表达式,找到符合正则表达式的结果
//System.out.println(IsFind);
//System.out.print(m.group()); //用于获取匹配后的结果
while(m.find()){
System.out.println(m.group()); //用于获取匹配后的结果
}
}
}
边界匹配器
^ | The beginning of a line 行开头 |
$ |
The end of a line 行结尾
"^ +正则表达式r1+$ " 文件不都是有一行一行的嘛.这个行开头,行结尾,在再中间插一个正则表达式,意思是说,正则表达式r1只会在一行中被使用
|
\b | A word boundary 单词边界 |
\B |
A non-word boundary 非单词的边界
String reg = "\\b[a-z]{3}\\b";
|
\A | The beginning of the input |
\G | The end of the previous match |
\Z | The end of the input but for the final terminator, if any |
\z | The end of the input |
到底用四中功能中的哪一个
- 如果只想知道该字符是否是对是错,使用匹配
- 想要将已有的字符串变成两一个字符串,替换
- 想要按照自定的方式将字符串变成多个字符串,切割.获取规则以外的子串
- 想要拿到符合需求的字符串子串,获取.获取符合规则的子串
System.out.println("matches:"+m.matches());
while(m.find()){
System.out.println(m.group()); //用于获取匹配后的结果
}
package zhengze;
import java.util.regex.*;
public class str {
public static void main(String[] args) {
getDemo();
}
public static void getDemo(){
String str = "ming tian jiu yao fang jia le ,da jia."; //将被提取的源字符串
String reg = "\\b[a-z]{4}\\b";
//---------------------------1
/*
* 将规则封装成对象
* */
Pattern p = Pattern.compile(reg);
//-----------------------------------------2
/*
* 让正则对象和要作用的字符串相关联.获取匹配器对象Matcher
* 有了匹配器对象之后,可以利用匹配器对象对字符串来进行多种操作
* */
Matcher m = p.matcher(str);
//-------------------------------------3
/*
* 将规则作用到字符串上,并进行符合规定的子串查找
* */
//Boolean IsFind = m.find(); //查看有没有按照正则表达式,找到符合正则表达式的结果
//System.out.println(IsFind);
//System.out.print(m.group()); //用于获取匹配后的结果
System.out.println("matches:"+m.matches());
while(m.find()){
System.out.println(m.group()); //用于获取匹配后的结果
}
}
}
- 这个例子的执行的结果是
matches:false
tian
fang
如果把 System.out.println("matches:"+m.matches()); 这行代码去掉的话,执行结果是:
ming
tian
fang
-
- 你会发现添加了System.out.println("matches:"+m.matches());这行代码 ming这行字符串就没有被打印出来.
- 为什么?因为m.matches() 会利用规则"\\b[a-z]{4}\\b" 去匹配这个str字符串.matches 函数要求这个str字符串长度有且仅的是4.
- 当matches() 用\\b[a-z]{4}\\b 匹配完之后ming 之后,发现ming 之后竟然还有内容.因此此时m.matches() 返回了false.
- 但是,此时匹配器m的指向str的指针已经由ming 中的字符"m",指向了tian 中的t .
- 当再执行m.find() 时,会从tian中字符"t" 这个位置开始进行匹配.所以才出现了返回的结果只有 tian fang
m.find() 在字符串中的指针的寻找过程
package zhengze;
import java.util.regex.*;
public class str {
public static void main(String[] args) {
getDemo();
}
public static void getDemo(){
String str = "mingtianjiuyaofangjiale ,da jia."; //将被提取的源字符串
String reg = "[a-z]{3}";
//---------------------------1
/*
* 将规则封装成对象
* */
Pattern p = Pattern.compile(reg);
//-----------------------------------------2
/*
* 让正则对象和要作用的字符串相关联.获取匹配器对象Matcher
* 有了匹配器对象之后,可以利用匹配器对象对字符串来进行多种操作
* */
Matcher m = p.matcher(str);
//-------------------------------------3
/*
* 将规则作用到字符串上,并进行符合规定的子串查找
* */
//Boolean IsFind = m.find(); //查看有没有按照正则表达式,找到符合正则表达式的结果
//System.out.println(IsFind);
//System.out.print(m.group()); //用于获取匹配后的结果
// System.out.println("matches:"+m.matches());
while(m.find()){
System.out.println(m.group()); //用于获取匹配后的结果
}
}
}
程序的运行结果是:
min
gti
anj
iuy
aof
ang
jia
jia
- 从这个例子可以发现,m.find() 当使用规则"[a-z]{3}" 把str字符串中的min 匹配到之后,下一个匹配它是从ming 的g位置开始匹配的.也就是说find()函数是把上第1次匹配结果的末尾,不管第1次匹配成功与否,当作了第2次匹配的开头.
正则表达式的例子
- 例1,图1
- 例2:Ip地址进行地址段的排序,分成A类,B类,C类地址
- 让Ip地址的第一个字段,如192.168.1.1 这个192就是Ip地址的第一个字段192 .按照字符串的自然顺序进行排序,只要让它们每一段都是3位即可.但是IP地址的第一段如果不是3位的话,要为这第一段进行补0操作,即保证每一段的位数都是3
- 如:2.168.3.25 第一段的2,不是三位数,所以要补成002
- 让Ip地址的第一个字段,如192.168.1.1 这个192就是Ip地址的第一个字段192 .按照字符串的自然顺序进行排序,只要让它们每一段都是3位即可.但是IP地址的第一段如果不是3位的话,要为这第一段进行补0操作,即保证每一段的位数都是3
package zhengze;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class str2 {
public static void main(String[] args) {
String ip = "192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
//-------------------------------1
String ip1 = ip.replaceAll("(\\d+)", "00$1");
//找到连续的数字(\\d+)之后,就把这个连续的数字封装成组,之后在这个组的前面加上两个0
//System.out.println(ip);
//00192.00168.001.00254 00102.0049.0023.00013 0010.0010.0010.0010 002.002.002.002 008.00109.0090.0030
//------------------------------------------2
String ip2 = ip1.replaceAll("0*(\\d{3})", "$1"); //将ip1再把多余的0都去除掉
//System.out.println(ip2);
//192.168.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030
//--------------------------------------3
String[] arr = ip2.split(" ");
TreeSet<String> ts = new TreeSet<String>();
for(String s:arr){
ts.add(s);
}
//-----------------------------4
for(String s: ts){
System.out.println(s.replaceAll("0*(\\d+)", "$1"));
//匹配前边的0个或多个0;把0后面的数字封装成组1,之后用组1把"0*(\\d+)" 都替换掉
}
}
}
- 例3.对邮件地址进行校验
package zhengze;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class str2 {
//-----------------------------1
public static void checkMail(){
String mail ="abc12@sina.com"; //首先要来一个地址
//-----------------------------2
String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+"; //
/*
* [a-zA-Z0-9_]+ 是指在@之前所有的字符,每一位只要是[a-zA-Z0-9_]中的某个字符就可以了.
* @之前的字符不必全部相等.但是要保证所有的字符都是[a-zA-Z0-9_]中的字符
* */
//-----------------------------------3
/*
* [a-zA-Z0-9_]+@[a-zA-Z0-9]+\\.[a-zA-Z]+
* [a-zA-Z0-9_]+ 指 @ 之前的所有的每一个字符都是[a-zA-Z0-9_]中的某个字符
* @[a-zA-Z0-9]+ 是指@之后的每一个字符都是[a-zA-z0-9]中的某个字符
*\\. 表示小数点
*[a-zA-Z]+ 表示 com cn这些符号
* */
//------------------------------------------4
/*
* 有的ip地址是 abc12@sina.com.cn.cn.cn
* "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+"
* (\\.[a-zA-Z]+)+ 表示 把[a-zA-Z]+封装成一个组,然后对这个组调用多次
* */
System.out.println(mail.matches(reg));
}
public static void main(String[] args) {
checkMail();
}
}
图: