1. java 初步认识正则 / 中括号表范围 / 预定义字符类\s \w \d / 边界匹配
package test.java.RegExp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Order {
public void RegexFirst() {
//简单认识正则表达式的概念,通过String 类的函数开始
System.out.println("abc".matches("..."));//点代表一个字符,有人叫他字符串匹配,其实他应该叫字符匹配,因为他是一个字符一个字符的匹配,
String replaceResult = "a8729a".replaceAll("\\d", "-");//替换所有的,这个方法非常好用。把这个字符串的所有数字替换成横线
System.out.println(replaceResult);
/
//认识一个另外两个类
Pattern p = Pattern.compile("[a-z]{3}");//compile 是把这个正则表达式编译一下,编译之后把他放到这个模式里面(Pattern就是字符串要被匹配的这样一个模式)
//而这个模式本身是需要编译一下的,如果不编译,每次现场马上编译,这个速度就会慢,你首先把这个模式编译好,编译好了,当你再拿这个模式
//去匹配其他字符串的时候,匹配起来的速度就会快一些,
//[a-z]这个模式是匹配一位字母,[a-z]{3}是匹配一个具有三个字符的字符串,而这三个字符中的每一个都是a到z 中的字母。
Matcher m = p.matcher("fgh");//匹配出来的结果,会存在另外一个类对象里面(匹配器Matcher ),背后的原理是,在内部的匹配过程是,他会创建一个有限状态的自动机。
System.out.println(m.matches());
/
System.out.println("fgh".matches("[a-z]{3}")); // 上面的三句话可以整合成下面的一句话,但是写上面的三句话有好处:第一个
//他的效率高了,你首先把他给编译了,你不用说现场马上编译了,除此之外,pattern 和matcher 提供了很多非常重要的功能,这是这个
//简单的函数所不具备的。
/
}
public static void main(String[] args) {
//1.初步认识. * + ? 点星加 问号,meta characters,meta的意思是元数据,这是几个比较特殊的字符,在正则表达式中往往有着特殊的含义。
//这个匹配(matches()函数)的意思,就是括号里的正则表达式所代表的字符串大集合,前面需要匹配的固定字符串是否在这个大集合中。
System.out.println("--------- 点 . * + ? 正则--------");
System.out.println("a".matches("."));
System.out.println("aa".matches("aa"));
System.out.println("aaaa".matches("a*"));// *代表的是0个或多个,API 文档里面 Pattern 类里有说明
System.out.println("aaaa".matches("a+"));// +代表一个或多个,
System.out.println("aaaa".matches("a?"));//false ?代表一个或0个
System.out.println("".matches("a*"));
System.out.println("21321321".matches("\\d{3,100}")); // 至少 3 次,但是不超过 100 次,也就是3到100位的数字,API 文档里面 Pattern 类里有说明
System.out.println("192.168.0.aaa".matches("\\d{1,3}\\.\\d{1,3}\\.\\d+\\.[a-z]+")); //这个就非常复杂了
System.out.println("192".matches("[0-2]{0,1}[0-9][0-9]"));//注意中括号说的是代表的值的范围,大括号说的是次数范围
System.out.println("http://www.baidu.com".matches("[a-z]+://[a-z]+\\.[a-z]{5}\\.[a-z]{3}"));
//2.范围正则
System.out.println("------范围正则------");
System.out.println("a".matches("[abc]")); //一个中括号只匹配一个字符,你中括号写的再长,他也是匹配一个字符,这个正则表达式的意思是
//请你给我取a,b,c三个字符中的一个
System.out.println("a".matches("[^abc]"));//小尖号位于“中括号里面的第一个字符”意思是取反,^代表取反,指取除了a,b,c字母之外的其他字母都可以
System.out.println("A".matches("[a-zA-Z]"));//取并集1,横线代表一个范围,取小写的a到z或者是大写的A到Z,横线 - 代表的是从哪个范围到哪个范围
System.out.println("A".matches("[a-z]|[A-Z]"));//取并集2,竖线代表或者,这个和上面的一样,只是用了两个中括号和 “或者”符号
System.out.println("A".matches("[a-z[A-Z]]"));//取并集3,这个和上面两个相同
System.out.println("B".matches("[A-C&&[B-E]]"));//取交集,A-Z之中的并且是RFG三者之一的
//3.认识\s \w \d \ 这些是预定义字符类
System.out.println("------ \\s \\w \\d \\ 特殊符号 正则------");//api 文档中Pattern 类中有说明
System.out.println(" \n\r\t".matches("\\s{4}"));//这个是true \s是空白字符,[ \t\n\x0B\f\r],第一个是空格字符,第二个t是table 键,n是换行,r是回车
System.out.println(" ".matches("\\S"));//false \S 是非空白字符:[^\s]
System.out.println("a_8".matches("\\w{3}"));// \w 是构成单词的字符, 是[a-zA-Z_0-9] ,意思是包括下横线还有0到9。用一个正则表达式\w 就能把[a-zA-Z_0-9]这么多字符匹配出来
System.out.println("abc888&^%".matches("[a-z]{1,3}\\d+[&^#%]+"));//小尖号位于“中括号里面的第一个字符”意思是取反,所以[&^#%]+ 匹配的是这四者之一出现一个或多次, \W 是非单词字符 [^\w]
System.out.println("---");
//字符串:在java中一个反斜线写在这,会和后面的字符合在一起构成转义字符,
//在java 中字符串,两个反斜线是一个反斜线,怎么用正则匹配出一个反斜线。所以java中一个反斜线必须用,两个反斜线来替代,
//正则表达式字符串:正则表达式中一个反斜线也会是一个特殊字符,他会和后面的字符合在一起构成转义字符
//正则表达式本身要用两个反斜线(正则字符串中)才能匹配字符串中的一个反斜线(api文档中Pattern 类中的规定),如上面代码,你要匹配两个反斜线,
//那么对应的正则表达式要用字符串表现出来的时候,每一个反斜线都要用两个反斜线替代(仔细读上面这句话,可以读懂),
//所以这里要用四个反斜线去匹配两个反斜线。从这个例子中可以看出来,正则表达式就是挨着盘的把需要匹配的字符串每个字符对应一遍,
//用杠杠通用的方式去对应,即可。从编译和运行方面对这个进行解释,如图1。
System.out.println("\\".matches("\\\\"));
//4.POSIX [pozix] Style 意思是POSIX 风格的字符类。用的不是特别多,简单记一下。POSIX是unix 操作系统的一套标准
System.out.println("a".matches("\\p{Lower}"));//不推荐这么写,别人这么写,自己在api 文档查一下即可
//5.边界匹配,指的是开头和结尾,
System.out.println("hello sir".matches("^h.*"));//true 小尖号位于“中括号里面的第一个字符”意思是取反,位于中括号外面代表“输入的开头”
System.out.println("hello sir".matches(".*ir$"));//true 以ir 结尾,
System.out.println("hello sir".matches("^h[a-z]{1,3}o\\b.*"));//true,\b 是单词边界,空格/换行/空白字符/各种各样的特殊字符,都算单词边界
System.out.println("hello sir".matches("^h[a-z]{1,3}o\\b sir"));//true
System.out.println("hello sir".matches("^h[a-z]{1,3}o\\bsir"));//false
System.out.println("hellosir".matches("^h[a-z]{1,3}o\\b.*"));//false,这里面o后面没有单词边界
}
}
图 1
2. 几个正则的例子
System.out.println("\n".matches("\\n"));//true 正则\\n 匹配换行符
System.out.println("\\n".matches("\\\\n"));//true
System.out.println("aaa 8888c".matches(".*\\d{4}."));//true
//单词边界说明,以下都算单词边界,如图2
System.out.println("aaa 8888c".matches(".{3}\\b \\d{4}."));//true
System.out.println("aaa 8888c".matches(".{3} \\b\\d{4}."));//true
System.out.println("aaa 8888c".matches(".{3} \\b \\d{4}."));//false
System.out.println("aaa 8888c".matches(".{3} \\d{4}."));//true 这说明先单词边界,再空格,先空格再单词边界都可以。只写空格不写单词边界也可以
//可以匹配email 地址的正则表达式
System.out.println("123456@qq.com".matches("[\\w[.-]]+@[\\w.-]+\\.\\w+"));//true
图2 这两个位置都算单词边界
3.。字符串也可以用竖线
p = Pattern.compile("(keyword:|fullname:|fullname2:)(.*?)(%20|&|\\)%20)"); // 注意这里必须加括号来分组,不然无法使用这个"或者"逻辑的正则
//结果用group( ) , group( 0 ) , group(1) , group(2) 来取得相应分组的结果
遇上面等价语句
line.replaceAll(".*(keyword|fullname|fullname2):(.*?)(&|%20AND).*", "$2") // $1 $2 等价于上面的group(1) group(2)
4..循环替换字符串中汉字中间的空格
while(keyword.matches("(.*[\u4e00-\u9fa5])(\\s+)([\u4e00-\u9fa5].*)")) {
keyword = keyword.replaceAll("(.*[\u4e00-\u9fa5])(\\s+)([\u4e00-\u9fa5].*)", "$1$3");
}
5..中括号里加上尖号是非
非字母的写法 [^a-zA-Z]