public class Demo9 { private static void p(Object o){ System.out.println(o); } public static void main(String[] args) { Pattern pattern = Pattern.compile("\\d{3,5}"); String s = "123-34345-234-00"; Matcher m = pattern.matcher(s); p(m.find());//true 匹配123成功 p("start: " + m.start() + " - end:" + m.end()); p(m.find());//true 匹配34345成功 p("start: " + m.start() + " - end:" + m.end()); p(m.find());//true 匹配234成功 p("start: " + m.start() + " - end:" + m.end()); p(m.find());//false 匹配00失败 try { p("start: " + m.start() + " - end:" + m.end()); }catch (Exception e){ System.out.println("报错了..."); } p(m.lookingAt()); p("start: " + m.start() + " - end:" + m.end()); } } //输出结果 true start: 0 - end:3 true start: 4 - end:9 true start: 10 - end:13 false 报错了... true start: 0 - end:3
替换字符串
•想要替换字符串首先要找到被替换的字符串, 这里要新介绍Matcher类中的一个方法group(), 它能返回匹配到的字符串.
•下面我们看一个例子, 把字符串中的java转换为大写.
public class Demo10 { private static void p(Object o){ System.out.println(o); } public static void main(String[] args) { Pattern p = Pattern.compile("java"); Matcher m = p.matcher("java Java JAVA JAva I love Java and you"); p(m.replaceAll("JAVA"));//replaceAll()方法会替换所有匹配到的字符串 } } //输出结果 JAVA Java JAVA JAva I love Java and you
升级: 不区分大小写查找并替换字符串
•为了在匹配的时候不区分大小写, 我们要在创建模板模板时指定大小写不敏感 public static void main(String[] args) { Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//指定为大小写不敏感的 Matcher m = p.matcher("java Java JAVA JAva I love Java and you"); p(m.replaceAll("JAVA")); } //输出结果 JAVA JAVA JAVA JAVA I love JAVA and you
再升级: 不区分大小写, 替换查找到的指定字符串•这里演示把查找到第奇数个字符串转换为大写, 第偶数个转换为小写
•这里会引入Matcher类中一个强大的方法appendReplacement(StringBuffer sb, String replacement), 它需要传入一个
StringBuffer进行字符串拼接.
public static void main(String[] args) { Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE); Matcher m = p.matcher("java Java JAVA JAva I love Java and you ?"); StringBuffer sb = new StringBuffer(); int index = 1; while(m.find()){ //m.appendReplacement(sb, (index++ & 1) == 0 ? "java" : "JAVA"); 较为简洁的写法 if((index & 1) == 0){//偶数 m.appendReplacement(sb, "java"); }else{ m.appendReplacement(sb, "JAVA"); } index++; } m.appendTail(sb);//把剩余的字符串加入 p(sb); } //输出结果 JAVA java JAVA java I love JAVA and you ?
分组•先从一个问题引入, 看下面这段代码
public static void main(String[] args) { Pattern p = Pattern.compile("\\d{3,5}[a-z]{2}"); String s = "123aa-5423zx-642oi-00"; Matcher m = p.matcher(s); while(m.find()){ p(m.group()); } } //输出结果 123aa 5423zx 642oi
•其中正则表达式"\\d{3,5}[a-z]{2}"表示3~5个数字跟上两个字母, 然后打印出每个匹配到的字符串.
•如果想要打印每个匹配串中的数字, 如何操作呢.
•首先你可能想到把匹配到的字符串再进行匹配, 但是这样太麻烦了, 分组机制可以帮助我们在正则表达式中进行分组.
•规定使用()进行分组, 这里我们把字母和数字各分为一组"(\\d{3,5})([a-z]{2})"
•然后在调用m.group(int group)方法时传入组号即可
•注意, 组号从0开始, 0组代表整个正则表达式, 从0之后, 就是在正则表达式中从左到右每一个左括号对应一个组. 在这个表达式中第1组是数字, 第2组是字母.
public static void main(String[] args) { Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})");//正则表达式为3~5个数字跟上两个字母 String s = "123aa-5423zx-642oi-00"; Matcher m = p.matcher(s); while(m.find()){ p(m.group(1)); } } //输出结果 123 5423 642
实战1: 抓取网页中的email地址(爬虫)•假设我们手头上有一些优质的资源, 打算分享给网友, 于是便到贴吧上发出一个留邮箱发资源的帖子. 没想到网友热情高涨, 留下了近百个邮箱. 但逐个复制发送太累了, 我们考虑用程序实现.
•这里不展开讲发邮件部分, 重点应用已经学到的正则表达式从网页中截取所有的邮箱地址.
•首先获取一个帖子的html代码随便找了一个, 点击跳转, 在浏览器中点击右键保存html文件
•接下来看代码: