黑马程序员--正则表达式
2015-04-01 17:00
405 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
正则表达式:符合一定规则的表达式。
String 类中提供的方法较简单,组合起来操作代码麻烦,
正则表达式是对字符串即便捷又简单的操作方法。
下面通过一个小例子来体现以下正则表达式。
通过上面的示例可以看出正则表达式,极大地简化了书写,让操作变得很方便。
正则表达式中常用的一些特殊符号:
字符类符号
正则表达式对字符串的具体操作:
1.匹配
boolean matches()方法。用规则匹配整个字符串,只要有一处不符合,就返回false
eg:
QQ匹配:[1-9]\d{4-14}
匹配手机号码:
要求:手机号段只有13***,15***,18***
手机号码匹配正则:1[358]\d{9}
2.切割
String[] split(String regex)
按照叠词切String str=”erkkbfdffdkkd”;
String regex=”“;
该怎么切呢?
3.替换
replaceAll(String regex,String replacement)
4.获取 按照规则把符合规则的子串取出
操作步骤:
与获取操作有关的类:
Pattern 该类无构造函数,根据经验该类会提供静态方法返回本类对象。
Pattern.compile(String regex);
Matcher 很吊的一个类,里面提供了各种方法
正则表达式解决问题比较通用的思考方式:
两个关于正则的小练习:
网页爬虫:
正则表达式:符合一定规则的表达式。
作用:专门用于操作字符串。 特点:用一些特定的符号来表示一些代码操作。这样就简化书写。 好处:可以简化对字符串的复杂操作。 所以学习正则表达式,就是在学习一些符号的使用 弊端:符号定义越多,正则越长,阅读性越差
String 类中提供的方法较简单,组合起来操作代码麻烦,
正则表达式是对字符串即便捷又简单的操作方法。
下面通过一个小例子来体现以下正则表达式。
/* 需求: 对QQ号码进行校验,要求5-15位,0不能开头,只能是数字 */ class CheckQQDemo { public static void main(String[] args) { //method_1("1254444454635555"); method("23434d5555"); } //使用正则表达式 public static void method_1(String qq) { String regex="[1-9][0-9]{4,14}"; boolean flag=qq.matches(regex); if(flag) System.out.println(qq+"..is ok"); else System.out.println(qq+".....no OK"); } //不使用正则表达式 //这种方式使用了String类中的方法进行组合完成需求,但是代码过于复杂 public static void method(String qq){ int len=qq.length(); if(len>=5&&len<=15) { if (!qq.startsWith("0")) { try { long l=Long.parseLong(qq); System.out.println("qq:"+qq); } catch (NumberFormatException e) { System.out.println("出现非法字符"); } /* char[] arr=qq.toCharArray(); boolean flag=false; for (int i=0; i<arr.length; i++) { if(!(arr[i]>'0'&&arr[i]<='9')) { flag=true; break; } } if(!flag) { System.out.println("qq:"+qq); } else { System.out.println("出现非法字符"); } */ } else { System.out.println("不可以0开头!"); } } else { System.out.println("长度错误"); } } }
通过上面的示例可以看出正则表达式,极大地简化了书写,让操作变得很方便。
正则表达式中常用的一些特殊符号:
字符类符号
[abc]可以判断一个字符串当中某一个字符位上出现的字符,a或b或c eg:a.matcheds("[bcd]"); 返回的是false。 [a-zA-Z] [^abc] [a-d[m-p]]a到d或m到p去交集 预定义字符: . 任意字符 \d 任意数字 使用时 \\d 注意在正则表达式中\\总是成对出现 \D 任意非数字 \s 空白字符[\t\n\0B\f\r] \S 非空白字符 \w 单词字符[a-zA-Z_0-9] 邮箱校验 \W 非单词字符 数量词: 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 输入的结尾
正则表达式对字符串的具体操作:
1.匹配
boolean matches()方法。用规则匹配整个字符串,只要有一处不符合,就返回false
eg:
QQ匹配:[1-9]\d{4-14}
匹配手机号码:
要求:手机号段只有13***,15***,18***
手机号码匹配正则:1[358]\d{9}
2.切割
String[] split(String regex)
public static void splitDemo() { /* String str="zhangsan lisi wangwu zhaoliu heh"; String reg=" +";//按照多个空格进行切割 */ /* String str="zhangsan.lisi.wangwu.zhaoliu.heh"; //String reg=".";//.是正则表达式中的符号,直接用.切出错 //想使用.必须先将.转义,给.转义的\也是正则表达式中的符号,所以需要把\也转义,即\\. String reg="\\."; */ /* String str="C:\\abc\\a.txt"; String reg="\\\\";//很特殊的部分,使用时一定要小心 */ //按照叠词切 String str="erkkbfdffdkkd"; String reg="(.)\\1"; String[] arr=str.split(reg); for (String s: arr) { System.out.println(s); } }
按照叠词切String str=”erkkbfdffdkkd”;
String regex=”“;
该怎么切呢?
这就涉及到了组的概念。 把要重用的部分用(.)括起来,通过\n的形式来捕获组"(.)\\1" 重用的部分超过2次"(.)\\1+" 为了让规则的结果被重用可以将规则封装成一个组。用()完成。 组的出现都有编号,从1开始。想要使用已有的组可以通过\n(n就是组的编号)的形式来获取 ((())()) 看有几组可以数()的个数,有几个()就有几组 组的出现就体现出来了正则表达式的弊端:阅读性极差
3.替换
replaceAll(String regex,String replacement)
public static void replaceAllDemo() { //模拟发帖子中带有qq账号信息,将带有的qq信息替换成# /* String str="wer1235555dd488488494654dfdfdg"; String reg="\\d{5,}"; str=str.replaceAll(reg,"#"); */ /* //将叠词替换成& String str="erkkbfdffdkkkkkkd"; String reg="(.)\\1+"; str=str.replaceAll(reg,"&"); */ //将叠词替换成单个字符kk-->k zzzz-->z String str="erkkbfzzzzdffdkkkkkkd"; String reg="(.)\\1+"; //★★★特殊 str=str.replaceAll(reg,"$1");//可以通过$获取前一个规则中的组 System.out.println(str); } }
4.获取 按照规则把符合规则的子串取出
操作步骤:
1.将正则表达式封装成对象 2.让正则对象和要操作的字符串相关联 3.关联后,获取正则匹配引擎 4.通过引擎对符合规则的子串进行操作,比如取出
与获取操作有关的类:
Pattern 该类无构造函数,根据经验该类会提供静态方法返回本类对象。
Pattern.compile(String regex);
Matcher 很吊的一个类,里面提供了各种方法
import java.util.regex.*; class RegexDemo { public static void main(String[] args) { getDemo(); } public static void getDemo() { //需求将字符串中连续三个字母的子串取出 eg:取出jiu yao jia String str="ming tian jiu yao fang jia le"; //String regex="\\w{4}";//单词有边界,这里需要使用单词边界匹配 String regex="\\b\\w{4}\\b"; //1.将规则封装成对象 Pattern p=Pattern.compile(regex); //2.让正则对象和要操作的字符串相关联。获取匹配器对象。 Matcher m=p.matcher(str); /* 学习到这里可以看出,String类中的matcher方法用的就是 Pattern和Matcher中的matcher方法,只不过是String类把 这些方法封装在了内部,用起来较为简单,但是功能单一, 想要使用更多复杂功能,就要回来找Pattern和Matcher类。 */ /* boolean b=m.find();//将规则作用到字符串上,并进行复核规则的子串查找 System.out.println(b); System.out.println(m.group());//获取匹配结果 */ //System.out.println(m.matches()); //一个小细节:如果下面的代码前面加上上面的这句m.matches(), //则输出结果会有可能发生错误,ming没有输出,这是因为一个匹 //配引擎内部使用的是同一个角标,而matches()方法作用于整个字 //符串,当匹配结束返回false,角标已经到了tian的t的位置,因 //此,调用find()方法,角标是从t的位置开始的,结果中就少了个ming。 //使用时一定要注意。 while(m.find()) { System.out.println(m.group()); } } }
正则表达式解决问题比较通用的思考方式:
1.如果只想知道该字符串是对是错,匹配。 2.想要将已有的变为另一个字符串,替换。 3.想要按照自定的方式将字符串变成多个字符串,切割。获取规则以外的子串 4.想要拿到符合需求的字符串子串,获取。 获取符合规则的子串
两个关于正则的小练习:
import java.util.*; class RegexTest { public static void main(String[] args) { //ipSort(); checkMail(); } /* 练习:将ip地址按照ip地址段顺序排序 192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.88 8.109.55.90 升序排序 思路: 还按照字符串自然顺序排列,只要让他们每一段三位即可 1.按照每一段需要的最多的0进行补齐,那么每一段就会至少保证三位。 2.将每一段只保留3位,这样,所有ip地址都是每一段三位 */ public static void ipSort() { String ip="192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.88 8.109.55.90"; ip=ip.replaceAll("(\\d+)","00$1"); System.out.println(ip); ip=ip.replaceAll("0*(\\d{3})","$1"); System.out.println(ip); String[] arr=ip.split(" +"); TreeSet<String> ts=new TreeSet<String>(); for (String s: arr) { ts.add(s); } for(String s:ts) { System.out.println(s.replaceAll("0*(\\d+)","$1")); } } /* 对邮箱校验 */ public static void checkMail() { String mail="avbdgf@sina.com.cn.hah.hgh"; //@前边固定,后边不固定 //可以有下划线 没下划线 没数字下划线 String regex="\\w{6,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";//较为精准的匹配 System.out.println(mail.matches(regex)); //regex="\\w+@\\w+(\\.\\w+)+";//相对不太精准的匹配 /* mail.indexOf("@")!=-1 //建立在大部分人都对邮箱格式熟知的基础上 */ } }
网页爬虫:
import java.io.*; import java.net.*; import java.util.regex.*; class RegexTest3 { public static void main(String[] args) throws Exception { //getMailsByIE(); getMails(); } /* 获取指定文档中的邮件地址 包含获取操作,需要用到Pattern和Matcher类 */ public static void getMails()throws Exception { BufferedReader bufr=new BufferedReader(new FileReader("mail.txt")); Pattern p= Pattern.compile("\\w{5,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}"); String line=null; PrintWriter out=new PrintWriter(new FileOutputStream("mailgeted.txt"),true); while ((line=bufr.readLine())!=null) { Matcher m=p.matcher(line); while(m.find()) { out.println(m.group()); //System.out.println(m.group()); } } out.close(); bufr.close(); } /*将网页中获取的邮箱地址存入文件中*/ public static void getMailsByIE()throws Exception { //百度贴吧上找了个带回复中有邮箱的网址 URL url=new URL("http://tieba.baidu.com/p/2314539885"); URLConnection uc=url.openConnection(); BufferedReader bufr=new BufferedReader(new InputStreamReader(uc.getInputStream())); Pattern p= Pattern.compile("\\w{5,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}"); String line=null; PrintWriter out=new PrintWriter(new FileOutputStream("mailgeted_1.txt"),true); while ((line=bufr.readLine())!=null) { Matcher m=p.matcher(line); while(m.find()) { //System.out.println(m.group()); out.println(m.group()); } } } }
相关文章推荐
- 黑马程序员--Java基础--正则表达式、反射机制
- 黑马程序员--正则表达式
- 黑马程序员:正则表达式
- 黑马程序员---正则表达式
- 黑马程序员---从头开始,回忆JAVA基础之正则表达式。
- 黑马程序员_Java学习日记21_正则表达式
- 黑马程序员 Java自学总结十七 正则表达式
- 黑马程序员-----正则表达式
- 黑马程序员 正则表达式笔记总结
- 黑马程序员---正则表达式
- 黑马程序员-Java-正则表达式-day25
- [黑马程序员](第25天)高新技术之正则表达式
- 黑马程序员-正则表达式、网页爬虫
- 黑马程序员——JAVA基础---正则表达式切割组的问题
- 黑马程序员--java学习之正则表达式
- 【黑马程序员】常用正则表达式字符
- 黑马程序员——JAVA基础之正则表达式,网络爬虫
- 黑马程序员 正则表达式
- 黑马程序员——正则表达式
- 黑马程序员——11 正则表达式