使用java正则表达式的正确姿势
文章目录
一、用途
- 用于字符串处理
- 字符串匹配
- 字符串查找
- 字符串替换
- 例子
- IP地址是否正确
- 从网页中揪出email地址
- 从网页中揪出链接等
- 使用的类
- java.lang.String
- java.util.regex.Pattern
- java.util.regex.Matcher
二、. * + ? 表示什么意思?
- *表示是一个字符
- X*表示X出现0个或多个
- X+表示出现1个或多个
- X?表示X出现0个或1个
- X{n}表示X出现n次
- X{n,}X最少出现n次,最多出现次数不限制
- X{n,m}X出现至少n次,不超过m次
- {}表示对字符出现次数的限制
- [-]表示限制字符范围
10.[a-z]表示字符范围只能是a-z
示例代码:
//初步认识. * + ? {} []
p("a".matches("."));//true
p("aa".matches("aa"));//true
p("aaaa".matches("a*"));//true
p("aaaa".matches("a+"));//true
p("".matches("a*"));//true
p("aaaa".matches("a?"));//false
p("".matches("a?"));//true
p("a".matches("a?"));//true
p("21234567898".matches("\\d{3,100}"));//true
p("192.168.0.aaa".matches("\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)"));//false
p("192".matches("[0-2][0-9][0-9]"));//true
private static void p(Object o){
System.out.println(o);
}
三、[]表示什么意思?(控制范围)
- []表示匹配[]内其中一个字符
- ^表示取反
- -表示范围
- |表示或者 &&表示并且
示例代码:
public static void main(String[] args) {
//范围
p("a".matches("[abc]"));//匹配abc其中的一个字符 true
p("a".matches("^abc"));//匹配abc之外的字符 false
//匹配a-z或者A-Z之间的字符 3种写法
p("A".matches("[a-zA-Z]"));//true
p("A".matches("[a-z]|[A-Z]"));//true
p("A".matches("[a-z[A-Z]]"));//true
p("R".matches("[A-Z&&[RFG]]"));//A-Z之间并且是RFG三者之一 true
}
private static void p(Object o){
System.out.println(o);
}
四、常用的"\字母"表示什么意思?
- \d表示0-9之间的数字 [0-9]
- \D表示除0-9之外的字符 [^0-9]
- \s表示一个空白字符[ \t\n\x0b\f\r] 包含空格tab键等
- \S表示不包含空白字符[^\s]
- \w表示包含构成英文单词的字符[a-zA-Z_0-9]
- \W表示不包含英文单词的字符[^\w]
示例:
//认识\s \w \d \
p(" \n\r\t".matches("\\s{4}"));//true
p(" ".matches("\\S"));//false
p("a_0".matches("\\w{3}"));//true
p("abc888&^%".matches("[a-z]{1,3}\\d+[&^%]+"));//true
p("\\".matches("\\\\"));// java比较反斜杠 true
private static void p(Object o){
System.out.println(o);
}
五、边界
^ 表示起始位置
$ 表示结束位置
\b表示一个单词的边界(边界指的是空格、换行、空白字符、tab键等)
示例:
//边界
p("hello sir".matches("^h.*"));//h开头后面跟0个或者多个字符 true
p("hello sir".matches(".*ir$"));//ir结尾前面有0个或者多个字符 true
p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));//h开头,o后面是否包含单词边界 true
p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));//h开头,o后面是否包含单词边界 false
private static void p(Object o){
System.out.println(o);
}
六、matches、find、lookingAt
matches匹配整个字符串
find找子串
lookAt从开始位置找
示例代码:
Pattern p = Pattern.compile("\\d{3,5}");//全部为数字,长度为3-5
String s = "123-23234-234-00";
Matcher m = p.matcher(s);
p(m.matches());//false
m.reset();//matches和find一起使用会出现问题,一般要加reset,否则输出结果会有出入
//find 依次查找子串
p(m.find());//true
//输出找到子串以后的开始位置和结束位置(前提是必须能找到这子串,否则会报错)
p(m.start() + "-" + m.end());//输出0-3
p(m.find());//true
p(m.start() + "-" + m.end());//输出4-9
p(m.find());//true
p(m.start() + "-" + m.end());//输出10-13
p(m.find());//false
//lookingAt从开始位置找,每次从开头开始找
p(m.lookingAt());//true
p(m.lookingAt());//true
p(m.lookingAt());//true
p(m.lookingAt());//true
}
private static void p(Object o){
System.out.println(o);
}
七、replacement字符串替换
示例代码:
//字符串替换replacement
Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java");
//把字符串中所有的java(忽略大小写),全部替换成大写的JAVA
p(matcher.replaceAll("JAVA"));
private static void p(Object o){
System.out.println(o);
}
输出结果如下:
示例代码2:
//字符串替换replacement
Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//忽略大小写
Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java the end");
//要求把找到的第一个java字符串编程大写,找到的第二个变成小写,依次类推
StringBuffer buffer = new StringBuffer();
int i = 0;
while (matcher.find()){
i++;
if(i % 2 == 0){
matcher.appendReplacement(buffer,"java");
}else {
matcher.appendReplacement(buffer,"JAVA");
}
}
matcher.appendTail(buffer);//加上尾巴
p(buffer);
}
private static void p(Object o){
System.out.println(o);
}
输出结果:
八、group分组
如何判断是第几组,数小括号就行
作用:抓取字符串中的部分内容
示例代码:
//分组
Pattern pattern = Pattern.compile("(\\d{3,5})([a-z]{2})");//匹配3-5位的数字,两个字母
String s = "123aa-345345bb-234cc-00";
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
//只输出3-5位的数字也就是第一组
p(matcher.group(1));
//只输出两位字母也就是第二组
// p(matcher.group(2));
private static void p(Object o){
System.out.println(o);
}
输出结果:
如果group传入的是2,则输出如下:
如果group什么都不传,则输出结果如下:
九、读取本地网页中的email地址
示例代码:
public class EmailSpider {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("E:\\留下你的电子邮箱地址,我们来写Email吧。.html"));
String line = "";
while ((line = br.readLine()) != null){
//判断有没有读到结尾
parse(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void parse(String line) {
Pattern pattern = Pattern.compile("^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
Matcher matcher = pattern.matcher(line);
while (matcher.find()){
System.out.println(matcher.group());
}
}
}
十、其他知识
向前引用:
示例代码:
//向前引用
Pattern pattern = Pattern.compile("(\\d\\d)\\1");
// \\1指的是后面找到的结果必须和第一个组捕捉的字符串一样
String s = "1214";//false
// String s = "1212";//true
Matcher matcher = pattern.matcher(s);
System.out.println(matcher.matches());
忽略大小写或者其他规则可以用下面这种写法:
//忽略大小写
//第一种写法
Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
//第二种写法
p("java".matches("(?i)(java)"));