正则表达式



正则表达式(Regular Expression)是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作。
正则表达式是一个非常实用的工具,用于匹配字符串的模版。
Java还提供了Pattern和Matcher两个类专门用于提供正则表达式的支持。

String类里提供了如下几个特殊方法:
boolean matches(String regex):判断该字符串是否匹配指定正则表达式。
String replaceAll(String regex, String replacement):返回该字符串中所有匹配正则表达式的子串替换成replacement后的新字符串。
String[] split(String regex):根据给定正则表达式拆分该字符串后得到的字符串数组。

上面这些特殊的方法都依赖于Java提供的正则表达式支持。

下面先列出一些常用的正则表达式的构造摘要。

      构造                            匹配
    --------------------------------------------
1)字符
      x                                  字符x  
      \\                              反斜线字符 

2)字符类
      [abc]                       a、b 或 c(简单类) 
      [^abc]                     任何字符,除了 a、b 或 c(否定) 
      [a-zA-Z]                  a 到 z 或 A 到 Z,两头的字母包括在内(范围) 

3)预定义字符类
     .                               任何字符(与行结束符可能匹配也可能不匹配) 
     \d                             数字:[0-9] 
     \D                            非数字: [^0-9] 
     \s                             空白字符:[ \t\n\x0B\f\r] 
     \S                            非空白字符:[^\s] 
     \w                            单词字符:[a-zA-Z_0-9] 
     \W                           非单词字符:[^\w] 

4)边界匹配器
     \b                            单词边界 
     \B                           非单词边界 

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

1.匹配
使用String类的方法matches(String regex)。
public class RegexDemo {

	public static void main(String[] args) {

		//字符串是否匹配邮箱格式
		String mail = "123yp@sina.com";
		String regex = "\\w+@[a-zA-Z]+(\\.[a-zA-Z]+){1,2}";
		
		System.out.println("该字符串是否符合邮箱格式:" + mail.matches(regex));
	}

}

2.切割
使用String类的方法split(String regex)。

下面程序将一个绝对路径切割成几个分路径。
public class RegexDemo {

	public static void main(String[] args) {

		//将下面路径切割成分路径
		String path = "c:\\java\\day1\\Hello.java";
		
		//切割成分路径,即将反斜线作为分隔符切割成几部分
		//因为是双反斜线,每个反斜线都要用一个反斜线转义,所以正则表达式是"\\\\"
		String regex = "\\\\";
		
		String[] paths = path.split(regex);
		for(String p : paths){
			System.out.println(p);
		}
	}
}


下面程序将ip地址分成4段
public class RegexDemo {

	public static void main(String[] args) {

		//将下面ip地址分段
		String ip = "192.168.10.10";
		
		//ip地址分段,即将点作为分隔符切割成几部分
		//因为在正则表达式中,点代表任意符号,所以要将点转义,而每个反斜线都要用一个反斜线转义,所以正则表达式是"\\."
		String regex = "\\.";
		
		String[] ips = ip.split(regex);
		for(String i : ips){
			System.out.println(i);
		}
	}
}

下面程序将一个字符串以叠词为分隔符来进行切割
1)叠词就是多个连续的相同字母。
2)这里要用到正则表达式中组的概念,组用一对小括号表示,“()”,小括号中是每个组的规则。每个组都有编号。
获取组的个数与每个组其自身编号的技巧:出现多少个左括号“(”就有几个组,并且左括号出现的次数即为该组的编号,如:((())())中有4组。
3)在同一个正则表达式字符串中,使用“\\n”来表示第n个组的引用(“\n代表引用第n组,但是反斜线也要转义”)。而在不同表达式中,使用美元符号“&n”来表示引用前一个字符串中第n个组。

所以叠词的正则表达式写法:([a-zA-Z])\\1+。
[a-zA-Z]代表任意一个字符的引用;([a-zA-Z])代表将这个字符作为一个规则,变成一个组;\\1代表引用第1组的规则,即和前一个字符相同的字符;+代表出现一次或多次。
public class RegexDemo {

	public static void main(String[] args) {

		//将下面字符串使用叠词作为分隔符来切割
		String str = "abcdekkabcdqqfakcls";
		
		//叠词的正则表达式
		String regex = "([a-zA-Z])\\1+";
		
		String[] strs = str.split(regex);
		for(String s : strs){
			System.out.println(s);
		}
	}
}

3.替换
使用String类的方法replaceAll(String regex, String replacement)。
public class RegexDemo {

	public static void main(String[] args) {

		//将下面语句变成“我要学编程”
		String str = "我我..要要.....学...学学学..编编编...编编...编编程...";
		
		//先将多余的省略号去掉
		str = str.replaceAll("\\.+", "");
		
		//将重复的字去掉
		//这里用到组的概念。每个任意的字为一个组
		//多个连续重复的字的正则表达式为"(.)\\1+"
		//替换成一个单一的字,即要引用前一个字符串中的组,用"$1"
		str = str.replaceAll("(.)\\1+", "$1");
		System.out.println(str);
	}

}

4.获取
Java提供了Pattern和Matcher类来使用正则表达式。
Pattern对象是正则表达式编译后在内容中的表示形式,而Matcher对象代表执行匹配所涉及的状态保留在其中。
使用步骤:
1)将正则表达式封装成对象。
2)将正则对象和要匹配的字符串相关联。
3)关联后,获取匹配器。
4)通过匹配器对符合规则的子串进行操作。

Pattern类没有构造器。
方法:
static Pattern compile(String regex):返回Pattern对象,将给定的正则表达式编译到模式中。
Matcher matcher(CharSequence input):返回一个Matcher对象,将给定的正则表达式编译到具有给定标志的模式中。这个方法将正则表达式和字符串关联。

Matcher类,一般通过Pattern对象的matcher方法返回一个Matcher对象。
方法:
boolean matches():尝试将整个区域与模式匹配。即返回整个目标字符串与正则表达式是否匹配。
boolean find():尝试查找与该模式匹配的输入序列的下一个子序列。
String group():返回由以前匹配操作所匹配的输入子序列。与find方法一起使用。
int start():返回以前匹配的初始索引。
int end();返回最后匹配字符之后的偏移量。
public class RegexDemo {

	public static void main(String[] args) {

		//查找字符串中是3个字母组成的单词
		String str = "ming tian jiu yao fang jia la";
		
		//正则表达式,\b代表单词边界
		String regex = "\\b[a-zA-Z]{3}\\b";
		
		//将正则表达式封装成对象
		Pattern p = Pattern.compile(regex);
		//将正则表达式和字符串关联并获取匹配器
		Matcher m = p.matcher(str);
		
		//查找
		while(m.find()){
			System.out.println(m.group());
		}
	}
}



练习1.  将字符串中的ip地址按分组顺序排序
public class RegexDemo {

	public static void main(String[] args) {

		//按字符串的比较来判断
		String ip = "192.168.0.1 10.10.10.10 8.30.5.7 102.49.7.89 2.2.2.2";
		
		//在每个ip地址段前补两个零,使得每段地址至少为3位
		ip  = ip.replaceAll("(\\d+)", "00$1");
		System.out.println(ip);
		
		//将每段地址多余的0去掉,使得每段地址只有3位
		ip = ip.replaceAll("0+(\\d{3})", "$1");
		System.out.println(ip);
		
		//将ip地址切割成为一个单独的ip地址
		String[] ips = ip.split(" ");
		
		//遍历数组
		//将数组元素按照字符串的自然顺序将其存到TreeSet中,这样也就进行了按自然顺序的排序
		TreeSet<String> set = new TreeSet<String>();
		for(String i : ips){
			set.add(i);
		}
		
		//将每段地址前面多余的0去掉并打印
		for(String i : set){
			System.out.println(i.replaceAll("0+(\\d+)", "$1"));
		}
	}

}


练习2   网页爬虫:获取某网页所有邮箱地址。
public class RegexDemo {

	public static void main(String[] args) throws Exception{

		//获取网页链接
		URL url = new URL("http://book.douban.com/subject/3072831/discussion/1295004/");
		URLConnection conn = url.openConnection();
		
		//输入流
		BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		
		//邮箱地址正则表达式
		String regex = "\\w+@[a-zA-Z]+(\\.[a-zA-Z]+){1,2}";
		//将正则表达式封装成对象
		Pattern p = Pattern.compile(regex);
		String line = null;
		while((line = in.readLine()) != null){
			
			//将正则表达式与字符串相关联
			Matcher m = p.matcher(line);
			//查找
			while(m.find()){
				System.out.println(m.group());
			}
		}
	}

}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值