黑马程序员技术交流社区

标题: 【阳哥笔记】Java基础之笔记系列—Day27(反射+正则)! [打印本页]

作者: 阳哥忠粉    时间: 2015-6-11 17:43
标题: 【阳哥笔记】Java基础之笔记系列—Day27(反射+正则)!

总链接:http://bbs.itheima.com/thread-200600-1-1.html

Chapter 10 反射+正则

    反射

    JAVA反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象方法的功能称为java语言的反射机制。

    动态获取类中信息,就是java反射。可以理解为对类的解剖。

    如果想要对指定名称的字节码文件进行加载并获取其中的内容并调用,这时就使用到了反射技术。

    P.S.
    所谓的框架就是对外提供一些接口,也就是功能扩展的标准,由实现类按照这个接口标准去实现。框架内部如果需要操纵这些实现类的对象完成某些操作,那么只需要把这些实现类的全名(包名+类名)写在某个配置文件中,框架代码只需要读取这个配置文件,就可以获取这个实现类的字节码文件,然后利用反射技术创建这个实现类的对象并且调用相应的方法完成一些操作。

    用于描述字节码的类就是Class类,创建对象,可以提取字节码文件中的内容,如字段、构造函数、一般函数。该类就可以获取字节码文件中的所有内容,那么反射就是依靠该类完成的。想要对一个类文件进行解剖,只要获取到该类的字节码文件对象即可。

    示例:获取字节码文件对象的3种方式
      
    Person.java
  1. package cn.itcast.bean;

  2. public class Person
  3. {
  4.         private int age;
  5.         private String name;

  6.     public Person(int age,String name){
  7.                 super();
  8.                 this.age = age;
  9.                 this.name = name;

  10.                 System.out.println("Person param run..." + this.name + ":" + this.age);
  11.         }

  12.         public Person(){
  13.                 super();

  14.                 System.out.println("person run");
  15.         }

  16.         public void show(){
  17.                 System.out.println(name + "...show run..." + age);
  18.         }

  19.         private void privateMethod(){
  20.                 System.out.println("method run");
  21.         }

  22.         public void paramMethod(String str,int num){
  23.                 System.out.println("paramMethod run..." + str + ":" + num);
  24.         }

  25.         public static void staticMethod(){
  26.                 System.out.println("static method run...");
  27.         }
  28. }
复制代码

    ReflectDemo.java
  1. import cn.itcast.bean.Person;

  2. //要想要对字节码文件进行解剖,必须要有字节码文件对象。
  3. public class ReflectDemo
  4. {
  5.         public static void main(String[] args) throws ClassNotFoundException {
  6.                 getClassObject_1();
  7.                 System.out.println("--------------------");
  8.                 getClassObject_2();
  9.                 System.out.println("--------------------");
  10.                 getClassObject_3();
  11.         }

  12.    /*
  13.         * 获取字节码对象的方式:
  14.         * 方式一:Object类中的getClass()方法的。
  15.         * 想要用这种方式,必须要明确具体的类,并创建对象。
  16.         * 麻烦。
  17.         */
  18.         public static void getClassObject_1(){
  19.                
  20.                 Person p = new Person();
  21.                 Class clazz = p.getClass();

  22.                 Person p1 = new Person();
  23.                 Class clazz1 = p1.getClass();

  24.                 System.out.println(clazz == clazz1);
  25.         }

  26.         /*
  27.         * 方式二:任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。
  28.         * 相对简单,但是还是要明确用到类中的静态成员。
  29.         * 还是不够扩展。
  30.         */
  31.         public static void getClassObject_2(){
  32.                
  33.                 Class clazz = Person.class;
  34.                 Class clazz1 = Person.class;

  35.                 System.out.println(clazz == clazz1);
  36.         }

  37.         /*
  38.         * 方式三:只要通过给定的类的字符串名称就可以获取该类,更为扩展。
  39.         * 可以用Class类中的方法完成。
  40.         * 该方法就是forName。
  41.         * 这种方法只要有名称即可,更为方便,扩展性更强。
  42.         */
  43.         public static void getClassObject_3() throws ClassNotFoundException {
  44.                
  45.                 //可以把类的字符串名称写到配置文件中,然后读取出来。
  46.                 String className = "cn.itcast.bean.Person";
  47.                 Class clazz = Class.forName(className);

  48.                 System.out.println(clazz);
  49.         }
  50. }
复制代码
    运行结果:

    示例:获取Class中的构造函数
  1. import cn.itcast.bean.Person;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.InvocationTargetException;

  4. public class ReflectDemo
  5. {
  6.         public static void main(String[] args) throws Exception {
  7.                 createNewObject_1();
  8.                 System.out.println("--------------------");
  9.                 createNewObject_2();
  10.         }

  11.         public static void createNewObject_1() throws ClassNotFoundException,InstantiationException,IllegalAccessException {
  12.                 //早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
  13.                 //并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象。
  14.                 //Person p = new Person();

  15.                 //现在:
  16.                 String name = "cn.itcast.bean.Person";
  17.                 //找寻该文件类文件,并加载进内存,并产生Class对象。
  18.                 Class clazz = Class.forName(name);
  19.                 //如何产生该类的对象呢?
  20.                 Object obj = clazz.newInstance();//调用Person的空参构造函数
  21.         }

  22.         public static void createNewObject_2() throws ClassNotFoundException,InstantiationException,NoSuchMethodException,IllegalAccessException,InvocationTargetException {

  23.                 //Person p = new Person("小强",39);

  24.                 /*
  25.                 * 当获取指定名称对应类中的所体现的对象时。
  26.                 * 而该对象初始化不使用空参数构造函数该怎么办呢?
  27.                 * 既然是通过指定的构造函数进行对象的初始化。
  28.                 * 所以应该先获取到该构造函数,通过字节码文件对象即可完成。
  29.                 * 该方法是:getConstructor(parameterTypes);
  30.                 */

  31.                 String name = "cn.itcast.bean.Person";
  32.                 //找寻该名称类文件,并加载进内存,并产生Class对象。
  33.                 Class clazz = Class.forName(name);
  34.                 //获取到了指定的构造函数对象
  35.                 Constructor constructor = clazz.getConstructor(int.class,String.class);
  36.                 //通过该构造器对象的newInstance方法进行对象的初始化。
  37.                 Object obj = constructor.newInstance(38,"小明");
  38.         }
  39. }
复制代码
    运行结果:

    示例:获取Class的字段
  1. import cn.itcast.bean.Person;
  2. import java.lang.reflect.Field;

  3. public class ReflectDemo
  4. {
  5.         public static void main(String[] args) throws Exception {
  6.                 getFieldDemo();
  7.         }
  8.         
  9.         /*
  10.         * 获取字节码文件中的字段。
  11.         */
  12.         public static void getFieldDemo() throws Exception {

  13.                 Class clazz = Class.forName("cn.itcast.bean.Person");
  14.                
  15.                 //getField只能获取所有可访问公共字段,private获取不到。
  16.                 //Field field = claszz.getField("age");

  17.                 //getDeclaredField可以获取到公共字段,也可以获取到私有字段。
  18.                 Field field = clazz.getDeclaredField("age");

  19.                 //对私有字段的访问取消权限检查,暴力访问。
  20.                 field.setAccessible(true);

  21.                 Object obj = clazz.newInstance();
  22.                
  23.                 //为对象的属性赋值
  24.                 field.set(obj,89);
  25.                
  26.                 //获取某对象的某属性值
  27.                 Object o = field.get(obj);

  28.                 System.out.println(field);
  29.         }
  30. }
复制代码
   运行结果:


   示例:获取Class中的方法
  1. import cn.itcast.bean.Person;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Constructor;

  4. public class ReflectDemo
  5. {
  6.         public static void main(String[] args) throws Exception {
  7.                 getMethodDemo_1();
  8.                 System.out.println("---------------------------");
  9.                 getMethodDemo_2();
  10.                 System.out.println("---------------------------");
  11.                 getMethodDemo_3();
  12.         }
  13.         
  14.         /*
  15.         * 获取指定Class中的公共函数。
  16.         */
  17.         public static void getMethodDemo_1() throws Exception {

  18.                 Class clazz = Class.forName("cn.itcast.bean.Person");
  19.                
  20.                 Method[] methods = clazz.getMethods();//获取的都是公有的方法

  21.                 methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包括私有。

  22.                 for(Method method : methods){
  23.                         System.out.println(method);
  24.                 }
  25.         }

  26.         public static void getMethodDemo_2() throws Exception {

  27.                 Class clazz = Class.forName("cn.itcast.bean.Person");
  28.                
  29.                 Method method = clazz.getMethod("show",null);//获取空参数一般方法

  30.                 Object obj = clazz.newInstance();

  31.                 Constructor constructor = clazz.getConstructor(int.class,String.class);
  32.                 obj = constructor.newInstance(37,"小明");

  33.                 method.invoke(obj,null);
  34.         }

  35.         public static void getMethodDemo_3() throws Exception {

  36.                 Class clazz = Class.forName("cn.itcast.bean.Person");
  37.                
  38.                 Method method = clazz.getMethod("paramMethod",String.class,int.class);//获取空参数一般方法

  39.                 Object obj = clazz.newInstance();

  40.                 Constructor constructor = clazz.getConstructor();
  41.                 obj = constructor.newInstance();

  42.                 method.invoke(obj,"小强",89);
  43.         }
  44. }
复制代码
    运行结果:

    练习:反射练习

    代码:


    PCI.java
  1. package cn.itcast.reflect.test;

  2. public interface PCI
  3. {
  4.         public void open();
  5.         public void close();
  6. }
复制代码

    SoundCard.java
  1. package cn.itcast.reflect.test;

  2. public class SoundCard implements PCI
  3. {
  4.         public void open(){
  5.                 System.out.println("sound open");
  6.         }

  7.         public void close(){
  8.                 System.out.println("sound close");
  9.         }
  10. }
复制代码

    NetCard.java
  1. package cn.itcast.reflect.test;

  2. public class NetCard implements PCI
  3. {
  4.         public void open(){
  5.                 System.out.println("net open");
  6.         }

  7.         public void close(){
  8.                 System.out.println("net close");
  9.         }
  10. }
复制代码

    Mainboard.java
  1. package cn.itcast.reflect.test;

  2. public class Mainboard
  3. {
  4.         public void run(){
  5.                 System.out.println("main board run...");
  6.         }

  7.         public void usePCI(PCI p){
  8.                 if(p != null){
  9.                         p.open();
  10.                         p.close();
  11.                 }
  12.         }
  13. }
复制代码
   
    pci.Properties
  1. pci1=cn.itcast.reflect.test.SoundCard
  2. pci2=cn.itcast.reflect.test.NetCard
复制代码

    ReflectTest.java
  1. package cn.itcast.reflect.test;

  2. import java.io.File;
  3. import java.io.FileInputStream;

  4. import java.util.Properties;

  5. /*
  6. * 电脑运行
  7. */
  8. public class ReflectTest
  9. {
  10.         public static void main(String[] args) throws Exception {
  11.                
  12.                 Mainboard mb = new Mainboard();
  13.         
  14.                 mb.run();
  15.                 //每次添加一个设备都需要修改代码传递一个新创建的对象
  16.                 //mb.usePCI(new SoundCard());
  17.                 //能不能不修改代码就可以完成这个动作
  18.                 //不用new完成,而是只获取其class文件,在内部实现创建对象的动作。
  19.                
  20.                 File configFile = new File("pci.properties");

  21.                 Properties prop = new Properties();
  22.                 FileInputStream fis = new FileInputStream(configFile);

  23.                 prop.load(fis);

  24.                 for(int x = 0; x < prop.size(); x++){

  25.                         String pciName = prop.getProperty("pci" + (x + 1));

  26.                         Class clazz = Class.forName(pciName);//用Class去加载这个pci子类

  27.                         PCI p = (PCI)clazz.newInstance();

  28.                         mb.usePCI(p);
  29.                 }

  30.                 fis.close();
  31.         }
  32. }
复制代码
    运行结果:

    正则

    示例:
  1. /*
  2. * 正则表达式。
  3. *
  4. * 正则表达式用于操作字符串数据。
  5. * 通过一些特定的符号来体现的。
  6. * 所以我们为了掌握正则表达式,必须要学习一些符号。
  7. *
  8. * 虽然简化了,但是阅读性差。
  9. */
  10. public class RegexDemo
  11. {
  12.         public static void main(String[] args){
  13.                 String qq = "123456701";
  14.                 //checkQQ(qq);

  15.                 //正则表达式。
  16.                 String regex = "[1-9][0-9]{4,14}";
  17.                 boolean b = qq.matches(regex);
  18.                 System.out.println(qq + ":" + b);
  19.         }
  20.         /*
  21.          * 需求:定义一个功能对QQ号进行校验。
  22.          * 需求:长度5~15,只能是数字,0不能开头。
  23.          */
  24.          public static void checkQQ(String qq){
  25.                
  26.                 int len = qq.length();

  27.                 if(len >= 5 && len <= 15){
  28.                         if(!qq.startsWith("0")){
  29.                                 try{
  30.                                         long l = Long.parseLong(qq);

  31.                                         System.out.println(l + ":正确");
  32.                                 }catch(NumberFormatException e){
  33.                                         System.out.println(qq + ":含有非法字符");
  34.                                 }
  35.                         }else{
  36.                                 System.out.println(qq + ":不能0开头");
  37.                         }
  38.                 }else{
  39.                         System.out.println(qq + ":长度错误");
  40.                 }
  41.          }
  42. }
复制代码
    运行结果:

    正则表达式常用构造摘要

    字符类
    [abc] a、b 或 c(简单类)
    [^abc] 任何字符,除了 a、b 或 c(否定)
    [a-zA-Z] a 到 z 或 A 到 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 输入的结尾

    示例:
  1. public class RegexDemo
  2. {
  3.         public static void main(String[] args){
  4.                
  5.                 String str = "aoob";
  6.                 String reg = "ao?b";

  7.                 boolean b = str.matches(reg);
  8.                 System.out.println(str + ":" + b);

  9.                 reg = "ao+b";
  10.                 b = str.matches(reg);
  11.                 System.out.println(str + ":" + b);

  12.                 str = "ab";
  13.                 reg = "ao+b";
  14.                 b = str.matches(reg);
  15.                 System.out.println(str + ":" + b);

  16.                 str = "ab";
  17.                 reg = "ao*b";
  18.                 b = str.matches(reg);
  19.                 System.out.println(str + ":" + b);

  20.                 str = "aooooooob";
  21.                 reg = "ao{4,}b";
  22.                 b = str.matches(reg);
  23.                 System.out.println(str + ":" + b);

  24.                 reg = "ao{4,6}b";
  25.                 b = str.matches(reg);
  26.                 System.out.println(str + ":" + b);
  27.         }
  28. }
复制代码
   运行结果:


    正则表达式常见功能:匹配、切割、替换、获取

    示例:
  1. import java.util.regex.Matcher;
  2. import java.util.regex.Pattern;

  3. public class RegexDemo
  4. {
  5.         public static void main(String[] args){
  6.                 functionDemo_1();
  7.                 System.out.println("------------------------");
  8.                 functionDemo_2();
  9.                 System.out.println("------------------------");
  10.                 functionDemo_3();
  11.                 System.out.println("------------------------");
  12.                 functionDemo_4();
  13.                 System.out.println("------------------------");
  14.                 functionDemo_5();
  15.                 System.out.println("------------------------");
  16.                 functionDemo_6();
  17.                 System.out.println("------------------------");
  18.                 functionDemo_7();
  19.         }

  20.         /*
  21.          * 正则表达式对字符串的常见操作
  22.          * 1. 匹配
  23.          *                其实使用的就是String类中的matches方法。
  24.          *
  25.          * 2. 切割
  26.          *                其实使用的就是String类中的split方法。
  27.          *
  28.          * 3. 替换
  29.          *
  30.          * 4. 获取
  31.          */

  32.          /*
  33.           * 演示匹配
  34.           */
  35.         public static void functionDemo_1(){
  36.                 //匹配手机号码是否正确
  37.                 String tel = "15800001111";

  38.                 String regex = "1[358]\\d{9}";

  39.                 boolean b = tel.matches(regex);

  40.                 System.out.println(tel + ":" + b);
  41.         }

  42.          /*
  43.           * 演示切割
  44.           */
  45.         public static void functionDemo_2(){
  46.                 String str = "zhangsan      xiaoqiang             zhaoliu";

  47.                 String[] names = str.split(" +");

  48.                 for(String name : names){
  49.                         System.out.println(name);
  50.                 }
  51.         }

  52.         public static void functionDemo_3(){
  53.                 String str = "zhangsan.xiaoqiang.zhaoliu";

  54.                 String[] names = str.split("\\.");

  55.                 for(String name : names){
  56.                         System.out.println(name);
  57.                 }
  58.         }

  59.         /*
  60.          * 在表达式 ((A)(B(C))) 中,存在四个这样的组:
  61.          * 1 ((A)(B(C)))
  62.          * 2 \A
  63.          * 3 (B(C))
  64.          * 4 (C)
  65.          * 组零始终代表整个表达式。
  66.          */
  67.         public static void functionDemo_4(){
  68.                 String str = "zhangsanttttxiaoqiangmmmmmzhaoliu";

  69.                 //(.)表示一组,\\1+表示与第1组相同的出现1次以上
  70.                 String[] names = str.split("(.)\\1+");

  71.                 for(String name : names){
  72.                         System.out.println(name);
  73.                 }
  74.         }

  75.          /*
  76.           * 演示替换
  77.           */
  78.         public static void functionDemo_5(){
  79.                 String str = "zhangsanttttxiaoqiangmmmmmzhaoliu";

  80.                 //$表示前一个参数的第一组
  81.                 str = str.replaceAll("(.)\\1+","$1");

  82.                 System.out.println(str);
  83.         }

  84.         public static void functionDemo_6(){
  85.                 String str = "15800001111";

  86.                 str = str.replaceAll("(\\d{3})(\\d{4})(\\d{4})","$1****$2");

  87.                 System.out.println(str);
  88.         }

  89.         /*
  90.           * 演示获取
  91.           * 将正则规则进行对象的封装。
  92.           * Pattern p = Pattern.compile("a*b");
  93.           * 通过正则对象的matcher方法字符串相关联。获取要对字符串操作的匹配器对象Matcher。
  94.           * boolean b = m.matches();
  95.           */
  96.         public static void functionDemo_7(){
  97.                 String str = "da jia hao,ming tian bu fang jia";

  98.                 // \\b表示单词边界
  99.                 String regex = "\\b[a-z]{3}\\b";

  100.                 //1. 将正则封装成对象
  101.                 Pattern p = Pattern.compile(regex);

  102.                 //2. 通过正则对象获取匹配器对象
  103.                 Matcher m = p.matcher(str);

  104.                 //使用Matcher对象的方法对字符串进行操作。
  105.                 //既然要获取三个字母组成的单词。
  106.                 //查找:find();
  107.                 while(m.find()){
  108.                         System.out.println(m.group());//获取匹配的子序列
  109.                         System.out.println(m.start() + ":" + m.end());
  110.                 }
  111.         }
  112. }
复制代码
   运行结果:


    P.S.

    1、Pattern类为正则表达式的编译表示形式。指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。

    练习1:
  1. public class RegexTest
  2. {
  3.         public static void main(String[] args){
  4.                 test();
  5.         }

  6.         /*
  7.          * 1. 治疗口吃:我我...我我...我我我我...要要要要...要要要要...学学学学学...学学编编...编编编编..编..编...程程...程程程
  8.          * 2. 对ip地址排序
  9.          * 3. 对邮件地址校验
  10.          */

  11.          /*
  12.           * 1. 治口吃
  13.           */
  14.           public static void test(){
  15.                 String str = "我我...我我...我我我我...要要要要...要要要要...学学学学学...学学编编...编编编编..编..编...程程...程程程";

  16.                 //1. 将字符串中.去掉,用替换。
  17.                 str = str.replaceAll("\\.+","");

  18.                 //2. 替换叠词
  19.                 str = str.replaceAll("(.)\\1+","$1");
  20.                 System.out.println(str);
  21.           }
  22. }
复制代码
    运行结果:


    练习2:
  1. import java.util.TreeSet;
  2. import java.io.PrintStream;

  3. public class RegexTest
  4. {
  5.         public static void main(String[] args){
  6.                 test();
  7.         }

  8.         /*
  9.          * ip地址排序。
  10.          * 192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55
  11.          */

  12.         public static void test(){
  13.                 String ip_str = "192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55";

  14.                 //1. 为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同。
  15.                 //所以,补零,按照每一位所需最多0进行补充,每一段都加两个0。

  16.                 ip_str = ip_str.replaceAll("(\\d+)","00$1");
  17.                 System.out.println(ip_str);

  18.                 //然后每一段保留数字3位。
  19.                 ip_str = ip_str.replaceAll("0*(\\d{3})","$1");
  20.                 System.out.println(ip_str);

  21.                 //1. 将ip地址切出。
  22.                 String[] ips = ip_str.split(" +");

  23.                 TreeSet<String> ts = new TreeSet<String>();
  24.                
  25.                 for(String ip : ips){
  26.                         ts.add(ip);
  27.                 }

  28.                 for(String ip : ts){
  29.                         System.out.println(ip.replaceAll("0*(\\d+)","$1"));
  30.                 }
  31.         }
  32. }
复制代码
   运行结果:

    练习3:

  1. import java.util.TreeSet;
  2. import java.io.PrintStream;

  3. public class RegexTest
  4. {
  5.         public static void main(String[] args){
  6.                 test();
  7.         }

  8.         //对邮件地址校验。        
  9.         public static void test(){

  10.                 String mail = "abc1@sina.com";

  11.                 String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{1,3})+";

  12.                 boolean b = mail.matches(regex);

  13.                 System.out.println(mail + ":" + b);
  14.         }
  15. }
复制代码
   运行结果:

    练习4:爬虫

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.io.BufferedReader;
  4. import java.io.FileReader;
  5. import java.util.regex.Matcher;
  6. import java.util.regex.Pattern;
  7. import java.io.IOException;

  8. /*
  9. * 网页爬虫:其实就是一个程序用于在互联网中获取符合指定规则的数据。
  10. * 爬取邮箱地址。
  11. */
  12. public class RegexTest
  13. {
  14.         public static void main(String[] args) throws IOException {
  15.                 List<String> list = getMails();
  16.         
  17.                 for(String mail : list){
  18.                         System.out.println(mail);
  19.                 }
  20.         }

  21.         public static List<String> getMails() throws IOException {
  22.                 //1. 读取源文件。
  23.                 BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));

  24.                 //2. 对读取的数据进行规则的匹配。从中获取符合规则的数据。
  25.                 String mail_regex = "\\w+@\\w+(\\.\\w+)+";

  26.                 List<String> list = new ArrayList<String>();

  27.                 Pattern p = Pattern.compile(mail_regex);

  28.                 String line = null;

  29.                 while((line = bufr.readLine()) != null){
  30.                         Matcher m = p.matcher(line);

  31.                         while(m.find()){
  32.                                 list.add(m.group());
  33.                         }
  34.                 }

  35.                 //3. 将符合规则的数据存储到集合中。
  36.                 return list;
  37.         }
  38. }
复制代码
   运行结果:

    从互联网上爬邮箱

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.io.BufferedReader;
  4. import java.util.regex.Matcher;
  5. import java.util.regex.Pattern;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.net.URL;

  9. public class RegexTest
  10. {
  11.         public static void main(String[] args) throws IOException {
  12.                 List<String> list = getMailsByWeb();
  13.         
  14.                 for(String mail : list){
  15.                         System.out.println(mail);
  16.                 }
  17.         }

  18.         public static List<String> getMailsByWeb() throws IOException {

  19.                 URL url = new URL("http://www.itheima.com/aboutt/1376.html");

  20.                 BufferedReader bufr = new BufferedReader(new InputStreamReader(url.openStream()));

  21.                 String mail_regex = "\\w+@\\w+(\\.\\w+)+";

  22.                 List<String> list = new ArrayList<String>();

  23.                 Pattern p = Pattern.compile(mail_regex);

  24.                 String line = null;

  25.                 while((line = bufr.readLine()) != null){
  26.                         Matcher m = p.matcher(line);

  27.                         while(m.find()){
  28.                                 list.add(m.group());
  29.                         }
  30.                 }

  31.                 return list;
  32.         }
  33. }
复制代码
   运行结果:


~END~






作者: 时光匆匆    时间: 2015-6-11 18:34
更完了,收藏慢慢看
作者: mouwengang    时间: 2015-6-11 18:34
太高深,现在还看不懂。
作者: 魏海洲    时间: 2015-6-11 19:12

太高深,现在还看不懂。
作者: itheima_llt    时间: 2015-6-11 19:40
欧耶,终于更完了,辛苦啦!我顶~~~
作者: cyd1058    时间: 2015-6-11 19:54
现在还没学到,可以提前预习一下
作者: coosea128    时间: 2015-6-11 20:06
努力学习!争取早日看懂~~~
作者: 流水0215    时间: 2015-6-11 20:54
收藏一下
作者: 那一世的苍白    时间: 2015-6-11 21:17
已收藏,多谢多谢
作者: jakemind    时间: 2015-6-11 21:20
刚好学到这!学习了……
作者: 中平    时间: 2015-6-11 23:25
全部收藏!!!!!
作者: 杜黎明    时间: 2015-6-11 23:28
。。。。路过学习
作者: yijian2033    时间: 2015-6-11 23:32
谢谢分享、、、、、、、、、
作者: 夜愿Relax    时间: 2015-6-12 00:07
非常详细啊,虽然还没学到。。
作者: 竹子    时间: 2015-6-12 08:57
终于更新完了
作者: 秋天-10    时间: 2015-6-12 09:08
阳哥威武
作者: 人在旅途~东营    时间: 2015-6-12 09:20
终于更新完了,谢谢王强老师!
作者: 谢永烽    时间: 2015-6-12 13:23
要是代码上多加点注释的话会很不错,只能结合自己的笔记和老师的一同复习了  辛苦了阳哥
作者: q19871127    时间: 2015-6-12 20:14
先收藏一下吧  反射 目前还看不懂
作者: 新缘    时间: 2015-6-12 21:05
赞一个。
作者: dsw675407772    时间: 2015-6-12 21:09
看不懂, 赞一个 我慢慢学
作者: New_PS    时间: 2015-6-12 21:21
收藏 天天看
作者: 城北一直晴。    时间: 2015-6-12 23:53
阳哥,你居然这么快、真是不眠不休啊。辛苦辛苦了
作者: heiheihehe    时间: 2015-6-15 20:57
大牛啊  崇拜了
作者: 王冲6060    时间: 2015-6-15 21:54
好东西,值得收藏
作者: 魏海洲    时间: 2015-6-15 23:45
太高深,完全看不懂。
作者: RockLee    时间: 2015-6-19 15:08
:):handshake
作者: 喻忠航    时间: 2015-6-22 16:23
为什么出来的那么晚,我们都走了才出来这么好的总结!!!!!
作者: wenweishan2015    时间: 2015-6-22 20:40
赞!!!
作者: 繁星中的白矮星    时间: 2015-6-23 13:12
顶一下!
作者: 李玉    时间: 2015-6-23 13:50
这章的视频已看过,再看笔记,别有一番滋味啊!
作者: 有艺术的刺客    时间: 2015-6-23 14:04
多谢阳哥,哈哈
作者: Happe_Sun    时间: 2015-6-23 15:00
学习学习
作者: 魏海洲    时间: 2015-6-25 18:58
更完了,收藏慢慢看
作者: Overheat    时间: 2015-6-25 23:48
感谢分享!!
作者: 水壶vs兔子    时间: 2015-6-26 08:38
应该属于高级教程了吧!哈哈,好好学习,早日学习高级教程!
作者: very爱    时间: 2015-6-28 23:00
还没有学到这里,先收藏
作者: Z、c    时间: 2015-7-7 22:35
一路跟完。。期待阳哥的新作
作者: wanghua1    时间: 2015-7-8 00:07
点个赞  !!!

作者: Geek_红影    时间: 2015-7-12 16:03
必须支持!!!感谢分享
作者: Vampire..    时间: 2015-7-13 14:00
学习了,总结的太好了

作者: 炎舞霜冬    时间: 2015-7-13 21:46
收藏了先等学了再看
作者: zxj35986847    时间: 2015-7-13 21:56
我只想说,大神真多,

学无止境,保重身体..
作者: joerk    时间: 2015-7-13 22:08
就是这块学的不咋样,阳哥果然强大!1:hug:
作者: maizi1912    时间: 2015-7-13 22:25
收藏一下    马上也要学了
作者: 妳的微笑    时间: 2015-7-13 23:19
老师辛苦啦。谢谢老师!:lol
作者: 逆袭白富美    时间: 2015-7-14 00:29
很好的样子
作者: 黑马和大灰狼    时间: 2015-7-14 00:30
支持支持
作者: Frank2008    时间: 2015-7-14 00:59
谢谢!一直在看,很好!
作者: 猫咪先生    时间: 2015-7-14 01:04
666。。给力!
作者: 星痕-凌    时间: 2015-7-15 21:52
现在还没学到,可以提前预习一下!!!!!!!!!!!!!!!!!!!
作者: pi408637535    时间: 2015-7-16 16:36
赞一个。
作者: pi408637535    时间: 2015-7-16 16:38
先收藏一下吧  反射 目前还看不懂
作者: Nemo    时间: 2015-7-19 19:56
反射不是重点吗?怎么好像内容不多啊
作者: lsunshine    时间: 2015-7-19 20:13
感谢分享
作者: Swornf、时年    时间: 2015-8-6 08:36
学习学习
作者: cl99025    时间: 2015-8-7 23:35
收藏  现在看不懂。
作者: xqtzzl521    时间: 2015-8-17 23:15
正在学的部分,很有用
作者: 迷茫不堪的年纪    时间: 2015-9-1 22:55
加油努力看懂把
作者: 加多宝    时间: 2015-9-15 23:51
。。。。。。。。。。。
作者: 1975532882    时间: 2015-9-17 15:02
收藏,争取能早日弄明白

作者: 果核中的大世界    时间: 2015-9-17 16:19
还有好久才学,先收藏再慢慢看
作者: 小二儿    时间: 2015-9-17 20:47
收藏了,谢谢分享
作者: 然后呢8908    时间: 2015-9-17 21:21
这么多啊,知道反射很重要也很难
作者: lemo    时间: 2015-9-25 12:59
谢谢老师  收收下了
作者: yangxuqiang    时间: 2015-9-30 21:37
什么时候才能看到这一节
作者: 金樽月    时间: 2015-10-5 16:50
太详细了,不愧是黑马!!!
作者: 风语    时间: 2015-10-5 17:14
学习学习
作者: smile的程序猿    时间: 2015-10-5 17:15
留名  还没学到
作者: 如梦丶似幻    时间: 2015-10-5 17:22
前来学习~~~~
作者: 1975532882    时间: 2015-10-12 07:55
赞,,,,,,,,,,,,,
作者: 1975532882    时间: 2015-10-12 07:56
牛逼,,,,,,,,,,,,,,,,,,

作者: 三川草民    时间: 2015-10-12 08:19
很好,很详细,先收藏了
作者: FCRandR    时间: 2015-10-22 23:23
看的辛苦,做的更辛苦。
作者: FCRandR    时间: 2015-10-27 11:10
反射,写的不太多呢?看视频也是看的有点糊涂
作者: 小鹿    时间: 2015-10-27 20:11
八错八错! 赞!大赞!
作者: fenger7    时间: 2015-10-28 06:49
好好的看看
作者: 超级宝贝乐爷    时间: 2015-11-26 19:12
还好阳哥笔记可以复制,出大问题了
作者: 传奇查    时间: 2015-11-26 19:41
太牛了~大神啊~膜拜下~
作者: 一江夜雨    时间: 2015-11-26 21:52
过来看看
作者: 冷光之神    时间: 2015-11-26 23:00
666                                 
作者: 流水落花    时间: 2015-11-26 23:48
慢慢看吧 辛苦了
作者: 周亚飞    时间: 2015-11-27 00:35
感谢大神的分享
作者: 3872982    时间: 2015-12-17 19:58

赞一个。
作者: s1714534118    时间: 2015-12-25 20:48
看不懂,感觉好难呀!~
作者: 潇湘夜雨    时间: 2015-12-25 21:31
刚刚在基础班学习,看到过这个课程内容,先收藏,定能用到.
作者: 凤凰城nash    时间: 2015-12-26 00:24
我感觉这两个挺重要的,收藏了
作者: 沐一风    时间: 2015-12-26 13:20

此关键字是来自语言的艺术意识!
作者: 李放    时间: 2015-12-26 21:27
收藏一下
作者: 鳌少宝    时间: 2015-12-27 22:27
支持阳哥
作者: lh951329230    时间: 2015-12-28 09:20
路过参考一下
作者: lktz    时间: 2016-2-22 01:27
标记标记
作者: 独行浪子    时间: 2016-3-5 10:19
马了 先收藏
作者: 13120298870    时间: 2016-5-12 23:12
表示已蒙圈,哈哈,继续努力中,我是拍不死的小强




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2