java正则表达式

正则表达式:符合一定规则的表达式

作用:用于专门操作字符串

虽然String类中有很多方法也可以实现,但是过于复杂


规则:

字符
x字符 x
\\反斜线字符
\0n带有八进制值 0 的字符 n (0 <= n <= 7)
\0nn带有八进制值 0 的字符 nn (0 <= n <= 7)
\0mnn带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh带有十六进制值 0x 的字符 hh
\uhhhh带有十六进制值 0x 的字符 hhhh
\t制表符 ('\u0009')
\n新行(换行)符 ('\u000A')
\r回车符 ('\u000D')
\f换页符 ('\u000C')
\a报警 (bell) 符 ('\u0007')
\e转义符 ('\u001B')
\cx对应于 x 的控制符

字符类
[abc]abc(简单类)
[^abc]任何字符,除了 abc(否定)
[a-zA-Z]azAZ,两头的字母包括在内(范围)
[a-d[m-p]]admp[a-dm-p](并集)
[a-z&&[def]]def(交集)
[a-z&&[^bc]]az,除了 bc[ad-z](减去)
[a-z&&[^m-p]]az,而非 mp[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]

Greedy 数量词
X?X,一次或一次也没有
X*X,零次或多次
X+X,一次或多次
X{n}X,恰好 n
X{n,}X,至少 n
X{n,m}X,至少 n 次,但是不超过 m

边界匹配器
^行的开头
$行的结尾
\b单词边界
\B非单词边界
\A输入的开头
\G上一个匹配的结尾
\Z输入的结尾,仅用于最后的结束符(如果有的话)
\z输入的结尾

上面的只是列举了常用的规则,想了解全部规则,可以参考我另外一篇博客(java中Pattern类)http://blog.csdn.net/manfulleo/article/details/51114353


关于java正则表达式Pattern类中Greedy,Rsluctant,Possessive的区别,可以参考luoweifu的博客 http://blog.csdn.net/luoweifu/article/details/42759439

 

1.匹配

 booleanmatches(String regex)
          告知此字符串是否匹配给定的正则表达式。
代码示例:
import java.util.regex.*;
public class Demo{
	public static void main(String[] args) {
		//第一种方法
		Pattern p = Pattern.compile(".*foo");  
	    String str1 = "xfooxxxxxxfoo";  
	    Matcher m = p.matcher(str1);  
	    boolean b = m.matches();
	    System.out.println(b); 
	    
	    //第二种方法
	    String regex = ".*foo";
	    String str2 = "xfooxxxxxxfoo";
	    System.out.println(str2.matches(regex));
	    
	    checkQQ();
	    checkTel();
	}
	
	//检测QQ格式
	//5-15位,只有数字,第一位不可以为0
	static void checkQQ(){
		String qq = "123a15a";
		String regex = "[1-9]\\d{4,19}";
		boolean flag = qq.matches(regex);
		System.out.println("qq..."+flag);
	}
	
	//检测电话号码格式
	//前三位为13x,15x,18x,总共11位,
	static void checkTel(){
		String tel = "13688888888";
		String regex = "1[358]\\d{9}";
		boolean flag = tel.matches(regex);
		System.out.println("tel..."+flag);
	}
}

2.切割

 String[]split(String regex)
          根据给定正则表达式的匹配拆分此字符串。
 String[]split(String regex, int limit)
          根据匹配给定的正则表达式来拆分此字符串。

代码示例:
import java.util.regex.*;
public class Demo{
	public static void main(String[] args) {
	    splitDemo("abc 123   iop"," +");
	    splitDemo("abc.123.iop","\\.");
	    splitDemo("c:\\desktop\\a.java","\\\\");
	    splitDemo("acssfwffgyyyyq","(.)\\1+");
	    //按照叠词完成切割,为了可以让规则的结果被重用,可以将规则封装成一个组,用()完成,组的出现都有编号,从1开始,想要使用已有的组可以用\n(n就是组的编号)的形式来过去==获取
	    //算几组,看左括号有几个即可,且编号从左往右1开始。比如((())()) 有4组
	} 
	
	public static void splitDemo(String str,String regex){
		String[] arr = str.split(regex);
		for(String s:arr){
			System.out.println(s);
		}
		System.out.println("-------");
	}
}

3.替换

 StringreplaceAll(String regex,String replacement)
          使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
 StringreplaceFirst(String regex,String replacement)
          使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。

代码示例:
import java.util.regex.*;
public class Demo{
	public static void main(String[] args) {
		//将字符串数组替换成#
		replaceDemo("wff15168411fwj548486fws15648978f","\\d{5,}","#");
		//将叠词替换成&
		replaceDemo("fwkkejqqqfizzzzzo","(.)\\1+","&");
		//将叠词换成叠词中一个字符
		replaceDemo("fwkkejqqqfizzzzzo","(.)\\1+","$1");
	} 

	public static void replaceDemo(String str,String regex,String newStr){
		str = str.replaceAll(regex, newStr);
		System.out.println(str);
		System.out.println("-------");
	}
}


4.获取

代码示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Demo{
	public static void main(String[] args) {
		getDemo();
	}
	
	public static void getDemo(){
		String str = "ming tian jiu yao fang jia le,huo ji.";
		String regex = "\\b[a-z]{4}\\b";
		System.out.println(str);
		//将规则封装成对象
		Pattern p = Pattern.compile(regex);
		
		//让正则对象和要作用的字符串相关联。获取匹配器对象
		Matcher m = p.matcher(str);
		
		//其实String类中的matches方法就是用Pattern和Matcher对象完成的,只不过被String对象封装后变简单了
		//System.out.println(m.matches());
		
		boolean b = m.matches();
		System.out.println("..."+b);
		
		//将规则作用到字符串上,并进行符合规则的字串查找
		while(m.find()){
			System.out.println(m.group());	//用于获取匹配后结果
			System.out.println(m.start()+"..."+m.end());
		}
	}
}


会发现ming没有打印,为什么?
因为m.find()之前,有m.matches()方法,表示已经匹配了一次,所以m.find()是从第二个单词开始查找

5.本地爬虫

获取本地文件中的所有邮箱:
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Demo{
	public static void main(String[] args) throws Exception {
		getLocalMails();
	}
	
	//获取本地文件中邮箱
	public static void getLocalMails() throws Exception{
		BufferedReader bufr = new BufferedReader(new FileReader("mail.txt"));
		String line = null;
		String mailRegex = "\\w+@\\w+(\\.\\w)+";
		Pattern pattern = Pattern.compile(mailRegex);
		while((line = bufr.readLine())!=null){
			Matcher matcher = pattern.matcher(line);
			while(matcher.find()){
				System.out.println(matcher.group());
			}
		}
	}
}

注意文件如果用相对路径时,要把文件放在项目目录下即可,如图是我的文件存放位置:


如果想要实现从网页获取信息,可以参考我另一篇博客(java网页爬虫)http://blog.csdn.net/manfulleo/article/details/51115781


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值