Java - 正则表达式 - Pattern - Matcher

正则表达式概念

所谓正则表达式就是处理字符串的特殊字符串
用途
	字符串匹配(字符匹配)
	字符串查找(是建立在匹配之上的查找)
	字符串替换(是建立在查找的结果之后的替换)
例如
	IP地址是否正确
	从网页中揪出Email地址
	从网页揪出链接
类
	java.lang.String
	java.util.regex.Pattern
	java.util.regex.Matcher
要点		
	//一个反斜线
	String str1 = "\\";
	//正则表达式的一个反斜线使用两个反斜线,在java中表示就再需要两个反斜线转义
	System.out.println(str1.matches("\\\\"));
	//POSIX Style,这种写法不建议使用,如果要使用查API
	System.out.println("a".matches("\\p{Lower}"));
	//空白行
	" \n".matches("^[\\s&&[^\n]]*\\n$");
	//邮箱
	String regex1 = "[\\w[.-]]+";
	String regex2 = "@";
	String regex3 = "[\\w[.-]]+";
	String regex4 = "\\.";
	String regex5 = "[\\w]+";
	String regex = regex1+regex2+regex3+regex4+regex5;
	System.out.println("156112846@qq.com".matches(regex));

正则表达式的基本语法

普通字符(字母,数字,汉字,下划线)		
	一个普通字符在表达式中只匹配与之相同的一个字符
	表达式k在字符串sky进行匹配时,将匹配成功
\r,\n,\t,\f
	表示回车符,换行符,制表符,换页符
.	
	任意一个字符
X?	
	表示X可以出现0次或者1次
X+	
	表示X可以出现1次或者多次
X*
	表示X可以出现任意次
X{n}
	表示X可以出现n次
X{m,n}
	表示X可以最少出现m次,最多出现n次
X{n,}
	表示X最少出现n次
[ ]
	匹配中括号中任意一个字符
[^ ]
	匹配中括号中字符之外的任意一个字符
\d
	表示0~9之间的任意一个数字字符,即[0-9]
\D
	表示0~9之外的任意数字字符,即[^0-9]
\r,\n,\t,\f
	表示回车符,换行符,制表符,换页符
\s
	表示空格,制表符,换页符等空白字符的任意一个
\S
	表示空白字符以外的任意一个字符,即[^\s]
\w
	表示字母,数字,下划线中的任意一个字符,即[a-zA-Z_0-9]
\W
	表示字母,数字,下划线以外的任意一个字符,即[^a-zA-Z_0-9]
^
	该符号不匹配任何字符,字符串开始的位置,即^h必须以h开头
$
	该符号不匹配任何字符,字符串结束的位置,即r$必须以r结尾
\b
	该符号不匹配任何字符,表示单词的边界
\B
	该符号不匹配任何字符,表示非单词的边界,即[^\b]
|
	用来连接两个表达式,表示或的关系
	X|Y 表示X或者Y中的任意字符
()
	作为一个单元,一个分组
\n(n表示一个数字)
	有分组的情况下,表示对分组的引用
	\1表示对分组1的引用
\
	转义字符,当一个符号自身有意义而又要表示这个字符的时候,就需要转义
	\^表示^,\$表示$
?
	如果在?,+,*,{n},{m,n},{n,}后面,表示次数按非贪婪模式进行匹配,
		即按照匹配模式进行最小限度的匹配

扩展内容


贪婪 VS 非贪婪 VS 独占

package com.itlwc;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) throws Exception {
		String str = "aaaa5bbbb6";

		/*
		 * 贪婪的
		 * 一次吃进最多的10个字符,不匹配,再吐出来一个,匹配了,结束了
		 */
		String regex1 = ".{3,10}[0-9]";
		Matcher m1 = Pattern.compile(regex1).matcher(str);
		if (m1.find())
			System.out.println(m1.start() + "-" + m1.end());
		else
			System.out.println("not match!");

		/*
		 * 非贪婪的
		 * 一次吃进最少的3个字符,然后看后面哪个是不是数字,
		 * 再吞一个,然后再看后面哪个是不是数字,匹配了,结束了
		 */
		regex1 = ".{3,10}?[0-9]";
		m1 = Pattern.compile(regex1).matcher(str);
		if (m1.find())
			System.out.println(m1.start() + "-" + m1.end());
		else
			System.out.println("not match!");

		/*
		 * 独占的
		 * 一次吃进最多的10个字符,不匹配,不吐出来,不匹配了,结束了
		 */
		regex1 = ".{3,10}+[0-9]";
		m1 = Pattern.compile(regex1).matcher(str);
		if (m1.find())
			System.out.println(m1.start() + "-" + m1.end());
		else
			System.out.println("not match!");
	}
}
/*
打印结果:
	0-10
	0-5
	not match!
*/

非捕获组

package com.itlwc;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) throws Exception {
		System.out.println("--打印以a结尾的子串---");
		String str = "444a66b";
		String regex = ".{3}a";
		Matcher m = Pattern.compile(regex).matcher(str);
		while (m.find())
			System.out.println(m.group());

		System.out.println("--打印以a结尾的子串,但不捕获a--");
		// 非捕获组,这块的意思是不捕获a,算在这三个字符之中的
		regex = ".{3}(?=a)";
		m = Pattern.compile(regex).matcher(str);
		while (m.find())
			System.out.println(m.group());

		System.out.println("--这个例子和上面例子相似,但结果出乎意料--");
		// 非捕获组,不算在这三个字符之中的
		regex = "(?=a).{3}";
		m = Pattern.compile(regex).matcher(str);
		while (m.find())
			System.out.println(m.group());

		System.out.println("--打印前面不能是a的子串");
		regex = "(?!a).{3}";
		m = Pattern.compile(regex).matcher(str);
		while (m.find())
			System.out.println(m.group());

		System.out.println("--这个例子和上面例子相似,结果需要注意--");
		// 这个是先找444,后面是a不匹配再找44a,后面不是a,匹配
		regex = ".{3}(?!a)";
		m = Pattern.compile(regex).matcher(str);
		while (m.find())
			System.out.println(m.group());

		regex = ".{3}(?<!a)";
	}
}
/*
打印结果:
	--打印以a结尾的子串---
	444a
	--打印以a结尾的子串,但不捕获a--
	444
	--这个例子和上面例子相似,但结果出乎意料--
	a66
	--打印前面不能是a的子串
	444
	66b
	--这个例子和上面例子相似,结果需要注意--
	44a
	66b
*/

向前引用

package com.itlwc;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) throws Exception {
		// 第一组找到12,\1的意思是后面的必须和第一组一样
		Matcher m1 = Pattern.compile("(\\d\\d)\\1").matcher("1212");
		System.out.println(m1.matches());
		
		//1212不匹配,121不匹配,122匹配
		Matcher m2 = Pattern.compile("(\\d(\\d))\\2").matcher("1212");
		System.out.println(m2.matches());
	}
}
/*
打印结果:
	true
	false
*/

flags简写

package com.itlwc;

import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) throws Exception {
		Pattern.compile("java", Pattern.CASE_INSENSITIVE);
		//上下代码是等价的
		System.out.println("JAVA".matches("(?i)(java)"));
		System.out.println("java".matches("(?i)(java)"));
	}
}
/*
打印结果:
	true
	true
*/

String中正则表达式的使用

package com.itlwc;

public class Test {
	public static void main(String[] args) throws Exception {
		String str = "abc:0000:defg";
		System.out.println(str.replace("0000","8765"));
		// 替换所有匹配正则表达式的
		System.out.println(str.replaceAll("\\d", "0"));
		// 只替换第一个匹配正则表达式的
		System.out.println(str.replaceFirst("\\d", "1"));
		// str是否匹配给定正则表达式
		System.out.println(str.matches(".{13}"));
		//拆分
		for(String s : str.split(":")){
			System.out.print(s+"\t");
		}
		System.out.println();
		//拆分几段
		for(String s : str.split(":",2)){
			System.out.print(s+"\t");
		} 
	}
}
/*
打印结果:
	abc:8765:defg
	abc:0000:defg
	abc:1000:defg
	true
	abc	0000	defg	
	abc	0000:defg
*/

Pattern概述

java.util.regex.Pattern 
	其对象表示通过编译的正则式,利用该类对象可以与任意字符串进行模式匹配
构造器
	Pattern类的构造器是private
声明
	public final class Pattern extends Object implements Serializable
创建Pattern的静态工厂
	public static Pattern compile(String regex)
		将指定正则式编译成Pattern对象返回
	public static Pattern compile(String regex,int flags)
		将指定正则式按照指定标志编译成Pattern对象返回

Pattern标志常量

public static final int CASE_INSENSITIVE
	将启动对ASCII字符不区分大小写匹配
public static final int UNICODE_CASE
	将启动Unicode字符不区分大小写匹配
public static final int DOTALL
	将启动dotall模式,该模式下,"."将表示任意字符,包括回车符

Pattern常用方法

package com.itlwc;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) throws Exception {
		// 编译好的模式用起来更快一些
		// 将给定的正则表达式编译到模式中
		Pattern p = Pattern.compile("[a-z]{3}");
		// 将给定的正则表达式编译到具有给定标志的模式中
		p = Pattern.compile("[a-z]{3}", Pattern.CASE_INSENSITIVE);
		// 返回此模式的匹配标志
		System.out.println(p.flags());
		// 匹配某个字符串之后的结果,这个有可能有很多个
		// 该方法返回表示将要被匹配字符序列的匹配器对象
		Matcher m = p.matcher("fgh");
		System.out.println(m.matches());
		// 编译给定正则表达式并尝试将给定输入与其匹配
		System.out.println(Pattern.matches("[a-z]{3}", "fgh"));
		// 返回在其中编译过此模式的正则表达式
		System.out.println(p.pattern());
		// 该方法返回指定字符串的模式文本表示
		System.out.println(Pattern.quote("abc"));
		// 匹配拆分
		String[] str1 = Pattern.compile(",").split("boo,and,foo");
		for (String s : str1) {
			System.out.print(s + "\t");
		}
		System.out.println();
		// 匹配拆分,拆分几段
		String[] str2 = Pattern.compile(":").split("boo:and:foo", 2);
		for (String s : str2) {
			System.out.print(s + "\t");
		}
	}
}
/*
打印结果:
	2
	true
	true
	[a-z]{3}
	\Qabc\E
	boo	and	foo	
	boo	and:foo	
*/ 

Matcher概述

java.util.regex.Matcher 匹配器 
声明  
    public final class Matcher extends Object implements MatchResult 

Matcher常用方法

package com.itlwc;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) throws Exception {
		Matcher m1 = Pattern.compile("\\d{3,5}").matcher("123-45682-152-00");
		// 返回由此匹配器解释的模式
		System.out.println(m1.pattern());
		// 只有整个字符序列完全匹配成功才返回true
		System.out.println(m1.matches());
		// 把原来吃点的吐出来恢复到从前的状态
		m1.reset();
		// 找一个和模式匹配的子串,找到之后正则表达式引擎会把第一个子串去掉
		System.out.println(m1.find());
		// 起始位置和结束位置,但必须能找到,否则报错
		System.out.println(m1.start() + "-" + m1.end());
		// 每次都从开始位置找
		System.out.println(m1.lookingAt());

		System.out.println("------------------------------");
		CharSequence cs = "java JAVA javaEE hiJAVA abcdefg";
		int i = Pattern.CASE_INSENSITIVE;
		Matcher m2 = Pattern.compile("java", i).matcher(cs);
		while (m2.find()) {
			// 分组,输出匹配到的子串
			System.out.print(m2.group() + "\t");
		}

		System.out.println();
		System.out.println("------------------------------");
		// 把java全部替换成JAVA
		System.out.println(m2.replaceAll("JAVA"));

		System.out.println("------------------------------");
		// 把单数java转换为小写,双数java转换为大写
		m2.reset();
		StringBuffer sb = new StringBuffer();
		int count = 0;// 奇数偶数的常量
		while (m2.find()) {
			count++;
			if (count % 2 == 0) {
				// 替换
				m2.appendReplacement(sb, "JAVA");
			} else {
				m2.appendReplacement(sb, "java");
			}
		}
		// 添加尾巴,否则abcdefg不显示
		m2.appendTail(sb);
		System.out.println(sb);

		System.out.println("------------------------------");
		// 取符合正则表达式
		Pattern p = Pattern.compile("\\d{3,5}[a-z]{2}");
		Matcher m3 = p.matcher("123aa-33345bb-234cc-00");
		while (m3.find()) {
			System.out.print(m3.group() + "\t");
		}
		System.out.println();
		// 使用分组取数字,有几个(就分了几组
		// 怎么知道是第几组,规律是(是第几个就是第几组
		p = Pattern.compile("(\\d{3,5})([a-z]{2})");
		m3 = p.matcher("123aa-33345bb-234cc-00");
		while (m3.find()) {
			// 只要第一组数字
			System.out.print(m3.group(1) + "\t");
		}
		m3.reset();
		System.out.println();
		while (m3.find()) {
			// 只要第一组字母
			System.out.print(m3.group(2) + "\t");
		}
	}
}
/*
打印结果:
	\d{3,5}
	false
	true
	0-3
	true
	------------------------------
	java	JAVA	java	JAVA	
	------------------------------
	JAVA JAVA JAVAEE hiJAVA abcdefg
	------------------------------
	java JAVA javaEE hiJAVA abcdefg
	------------------------------
	123aa	33345bb	234cc	
	123	33345	234	
	aa	bb	cc
*/

网页中揪出Email

package com.itlwc;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) throws Exception {
		FileReader fr = new FileReader("D:\\email.html");
		BufferedReader br = new BufferedReader(fr);
		String line = "";
		while ((line = br.readLine()) != null) {
			parse(line);
		}
	}

	private static void parse(String line) {
		Pattern p = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");
		Matcher m = p.matcher(line);
		while (m.find()) {
			System.out.println(m.group());
		}
	}
}


  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值