Java笔记---正则表达式
2015-10-07 23:35
573 查看
一、正则表达式概述:
符合一定规则的表达式。作用是专门用于操作字符串。虽然我们在前面学习了对于字符串的操作,但是我们在要去操作复杂的字符串时,如果还选用以前的方式,那么代码会变得很复杂,那么操作方便又快的方式就是正则表达式了。简化对字符串的复杂操作。
特点:用于一些特定的符号来表示一些代码操作。这样就简化了书写。所以学习正则表达式就是在学习一些特殊符号的使用。
在上面的代码中我们先使用了String的一系列的方法来对字符串进行校验,我们可以看出来,方法很多,而且很多判断。很复杂,然后我们直接使用异常来进行处理,代码还是显得很复杂,所以我们就用了第二种方法,正则表达式,我们可以看到上面的checkQQ_2这个方法我们使用了正则表达式来判断这个qq是否合法,我们在判断这个qq的时候只需要知道这个是不是正确的就行了,我们正则表达式就直接返回了true和false。代码变得非常的简单,本来好几行的代码,现在三句话就全部搞定,这样我们也看出了正则表达式的好处。
二、具体操作功能:
1)、匹配: String matches方法。
字符类:
预定义字符类:
注意:在正则表达式中\是成对出现的,并不是转义字符。
Greedy数量词:
匹配是拿整个字符串根据规则去判断,如果判断到某部分为false了,就匹配失败,返回false
手机号匹配:
为了可以让规则的结果被重复使用,可以将规则封装成一个组用()完成,组的出现都有编号,从1开始,想要使用已有的组,可以通过 \n(n就是组的编号)的形式来获取。
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
3)、替换 String replaceAll();
操作步骤:
1、将正则表达式封装成对象
2、让正则对象和要操作的字符串相关联
3、关联后,获取正则匹配引擎
4、通过引擎对符合规则的子串进行操作,比如:取出
打印结果:
我们在while循环中通过调用matches方法,我们可以看到返回的值是false,为什么会出现这种情况呢,因为我们的规则是作用于整个字符串,当前面四个与规则匹配完之后后面的空格已经不符合我们的规则,所以他返回了false,但是我们的指针还在继续走,这时候我们的指针就移到了t上,然后从t开始又继续匹配,后面的依次类推,所以第二次去匹配的时候是不会从头开始的,因为我们的索引发生了变化,同一个匹配器的索引是相同的。
正则表达式练习:
所谓的网页爬虫就是一段小程序,这段程序会去将网页上指定的信息取出来。我们以获取网页中的邮件地址为例:
以上就是正则表达式的内容,文章还有很多的不足之处,望指出!谢谢
符合一定规则的表达式。作用是专门用于操作字符串。虽然我们在前面学习了对于字符串的操作,但是我们在要去操作复杂的字符串时,如果还选用以前的方式,那么代码会变得很复杂,那么操作方便又快的方式就是正则表达式了。简化对字符串的复杂操作。
特点:用于一些特定的符号来表示一些代码操作。这样就简化了书写。所以学习正则表达式就是在学习一些特殊符号的使用。
public class RegexDemo { public static void main(String[] args) { chekQQ_1(); } public static void chekQQ_1(){ String qq = "2450897"; //第一位是1-9的数字,第二位是0-9的数字并且出现了4-14次 String reg = "[1-9][0-9]{4,14}"; if(qq.matches(reg))//将规则和字符串相关联 System.out.println(qq+".....is ok"); else System.out.println(qq+"......is nono"); } /* * 对qq好进行校验 需求:5-15位,0不能开头,只能是数字 * * 这种方式,是使用了String类中方法进行组合完成了需求,但是代码啊过于复杂 */ public static void chekQQ() { String qq = "2456897"; int len = qq.length(); if (len >= 5 && len <= 15) { if (!(qq.startsWith("0"))) {//判断是否以0开头 try { long l = Long.parseLong(qq); System.out.println(l); } catch (NumberFormatException e) { System.out.println("出现非法字符"); } /*char[] arr = qq.toCharArray(); boolean flag = true; for (char ch : arr) { if (!(ch >= '0' && ch <= '9')) { flag = false; break; } } if (flag) { System.out.println(qq); }else{ System.out.println("非法字符"); } */ } else { System.out.println("不可以以0开头"); } }else{ System.out.println("必须是5到15位的数字"); } } }
在上面的代码中我们先使用了String的一系列的方法来对字符串进行校验,我们可以看出来,方法很多,而且很多判断。很复杂,然后我们直接使用异常来进行处理,代码还是显得很复杂,所以我们就用了第二种方法,正则表达式,我们可以看到上面的checkQQ_2这个方法我们使用了正则表达式来判断这个qq是否合法,我们在判断这个qq的时候只需要知道这个是不是正确的就行了,我们正则表达式就直接返回了true和false。代码变得非常的简单,本来好几行的代码,现在三句话就全部搞定,这样我们也看出了正则表达式的好处。
二、具体操作功能:
1)、匹配: String matches方法。
字符类:
[abc] | a、b 或 c(简单类) |
[^abc] | 任何字符,除了 a、b 或 c(否定) |
[a-zA-Z] | a 到 z 或 A 到 Z,两头的字母包括在内(范围) |
[a-d[m-p]] | a 到 d 或 m 到 p:[a-dm-p](并集) |
[a-z&&[def]] | d、e 或 f(交集) |
[a-z&&[^bc]] | a 到 z,除了 b 和 c:[ad-z](减去) |
[a-z&&[^m-p]] | a 到 z,而非 m 到 p:[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 次 |
手机号匹配:
//手机号匹配 //并且是以13xxx 15xxx 18xxx public static void checkTel(){ String tel = ""; String reg = "1[358]\\d{9}"; System.out.println(tel.matches(reg));2)、切割:String split();
为了可以让规则的结果被重复使用,可以将规则封装成一个组用()完成,组的出现都有编号,从1开始,想要使用已有的组,可以通过 \n(n就是组的编号)的形式来获取。
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 | ((A)(B(C))) |
---|---|
2 | \A |
3 | (B(C)) |
4 | (C) |
public static void splitDemo(){ String str = "zhangsan lisi wangwu"; // str = "c:\\abc\\a.txt"; str = "adcaafghkkkkkasd"; // String reg = " +";//按照多个空格来切割 // String reg = "\\\\"; String reg = "(.)\\1+";//按照叠词来切割 String[] arr = str.split(reg);//按照规则进行切割 for(String s : arr){ System.out.println(s); } }因为这些组的出现,我们也可以看出正则表达式的缺点:就是阅读性极差。
3)、替换 String replaceAll();
String str = "aasd12315612agah547789jfdh";//将字符串中的数字替换成# replaceAll(str,"\\d{5,}","#"); String str1 = "aasdasdsdd2agahdhdghggjfdh";//将字符串中的叠词替换成# //将重叠的字符替换成单个字母 // replaceAll(str1,"(.)\\1+","&"); replaceAll(str1,"(.)\\1+","$1"); public 4000 static void replaceAll(String oldStr,String reg,String newStr){ oldStr = oldStr.replaceAll(reg, newStr);//按照指定的规则进行替换 System.out.println(oldStr); }4)、获取:将字符串中符合规则的子串取出
操作步骤:
1、将正则表达式封装成对象
2、让正则对象和要操作的字符串相关联
3、关联后,获取正则匹配引擎
4、通过引擎对符合规则的子串进行操作,比如:取出
/*4、获取:将字符串中符合规则的子串取出 * * 操作步骤: * 1、将正则表达式封装成对象 * 2、让正则对象和要操作的字符串相关联 * 3、关联后,获取正则匹配引擎 * 4、通过引擎对符合规则的子串进行操作,比如:取出 */ import java.util.regex.*; public class RegexDemo2 { public static void main(String[] args) { getDemo(); } public static void getDemo(){ String str = "ming tian jiu yao fang jia le,da jia"; // str="123456"; // String reg = "[1-9]\\d{4,14}"; String reg = "\\b[a-z]{4}\\b"; //将规则封装成对象 Pattern p = Pattern.compile(reg); //将正则对象和字符串相关联,获取匹配器对象 Matcher m = p.matcher(str); // System.out.println(m.matches());//其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的,只不过被String的方法封装后用起来较为简单,但是功能却单一 //将 规则作用到字符串上,并进行符合规则的子串查找 // boolean b = m.find(); // System.out.println(b); // // //获取匹配后的结果 // System.out.println(m.group()); while(m.find()){ System.out.println(m.group()); } } }
打印结果:
我们在while循环中通过调用matches方法,我们可以看到返回的值是false,为什么会出现这种情况呢,因为我们的规则是作用于整个字符串,当前面四个与规则匹配完之后后面的空格已经不符合我们的规则,所以他返回了false,但是我们的指针还在继续走,这时候我们的指针就移到了t上,然后从t开始又继续匹配,后面的依次类推,所以第二次去匹配的时候是不会从头开始的,因为我们的索引发生了变化,同一个匹配器的索引是相同的。
正则表达式练习:
import java.util.TreeSet; /* * * * 到底使用四种功能中的哪一种呢?或者哪几个呢? * 思路方式: * 1、如果只想知道该字符串是否对错,用匹配 * 2、想要将已有的字符串变成另一个字符串,替换 * 3、想要按照自定义的方式将字符串变成多个字符串。切割,获取规则意外的字符串 * 4、想要拿到符合规则的字符串,获取。获取符合规则的字符串 */ public class RegexTest { public static void main(String[] args) { // test_1(); // ipSort(); checkMail(); } /* * 需求:对邮件地址进行校验, */ public static void checkMail() { String mail = "abc@sina.com"; String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";// 较为精确的匹配 reg = "\\w+@+\\w+(\\.\\w+)+";// 相对不精确的匹配 但是1@1.1这样的地址他也匹配 System.out.println(mail.matches(reg)); } /* * 需求: 将下列字符串转成:我要学编程。 */ public static void test_1() { String str = "我我...我我...我要..要要...要要...学学学...学学...编编编...编程..程.程程...程...程"; /* * 将已有的字符串变成另一个字符串,使用替换功能 1、先将.去掉 2、再将多个重复的内容变成单个内容 */ str = str.replaceAll("\\.+", ""); str = str.replaceAll("(.)\\1+", "$1"); System.out.println(str); } /* * 需求:192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30; * 将ip地址进行地址段顺序的排序 * * * 还按照字符串自然顺序,只要让他们每一段都是三位即可 1、按照每一段需要最多的0进行补齐,那么每一段至少都能保证有3位 * 2、将每一段只保留三位,这样所有的ip地址都是每一段三位 */ public static void ipSort() { String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30"; ip = ip.replaceAll("(\\d+)", "00$1"); ip = ip.replaceAll("0*(\\d{3})", "$1"); String[] str = ip.split(" +"); // 定义一个TreeSet集合,他会自动按照自然顺序排序 TreeSet<String> ts = new TreeSet<String>(); for (String s : str) { ts.add(s); } for (String s : ts) { System.out.println(s.replaceAll("0*(\\d+)", "$1")); } } }正则表达式之网页爬虫:
所谓的网页爬虫就是一段小程序,这段程序会去将网页上指定的信息取出来。我们以获取网页中的邮件地址为例:
import java.io.*; import java.net.*; import java.util.regex.*; public class RegexTest2 { public static void main(String[] args) throws Exception { getMails_2(); } /* * 从网上获取邮件地址 */ public static void getMails_2() throws Exception { URL url = new URL("http://192.168.70.1:8888//myweb/mail.html"); URLConnection conn = url.openConnection(); BufferedReader bufr = new BufferedReader(new InputStreamReader( conn.getInputStream())); String line = null; String reg = "\\w+@+\\w+(\\.\\w+)"; Pattern p = Pattern.compile(reg); while ((line = bufr.readLine()) != null) { match(line, p); } } /* * 获取指定文档中的邮件地址 使用获取功能,Pattern Matcher */ public static void getMails() throws Exception { BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.txt")); String line = null; String reg = "\\w+@+\\w+(\\.\\w+)";//定义邮箱规则 Pattern p = Pattern.compile(reg);//将规则封装成对象 while ((line = bufr.readLine()) != null) { match(line, p); } } public static void match(String str, Pattern p) { Matcher m = p.matcher(str); while (m.find()) {//先进行查找 System.out.println(m.group());//打印 } } }
以上就是正则表达式的内容,文章还有很多的不足之处,望指出!谢谢
相关文章推荐
- Windows平台的Eclipse-javaEE-mars相关配置
- Java新手如何学习Spring、Struts、Hibernate三大框架?(转)
- Java多线程死锁
- java作业2
- JavaWeb登陆成功后跳转到上一个页面
- Java中对变量范围转换引发的思考
- 有关Genymotion与eclipse的连接其他方法
- 其他对象(java基础)
- 关于abstract 与接口的比较
- 八大排序的java实现(上)
- Java优化
- Spring中Bean的Scope
- IntelliJ IDEA生成javadoc时乱码问题的解决
- eclipse安装图形界面插件
- ***4.34-游戏:剪刀石头布
- java
- java.sql.date与java.util.date区别以及数据库中插入带时分秒的时间
- 关于equals和==之间的区别(举例说明)
- 02-java语言基础
- Java继承