JAVA-常用API(二)

目录

1.Arrays

1.1认识Arrays

 1.2Arrays的排序

 2.JDK8的新特性:Lambda表达式

2.1认识Lambda表达式

 2.2用Lambda表达式简化代码、省略规则

3.JDK8的新特性:方法引用(进一步简化Lambda表达式)

3.1 静态方法引用

3.2 实例方法引用

3.3 特定类型方法的引用

3.4 构造器引用

4.常见算法

4.1 冒泡​编辑

4.2 选择排序

4.3 二分查找

5.正则表达式

5.1 概述

5.2 正则表达式书写规则

 5.3 正则表达式案例

5.4 正则爬取内容

5.5 搜索、分割


1.Arrays

1.1认识Arrays

package com.itheima.d1_array;

import java.util.Arrays;
import java.util.function.IntToDoubleFunction;

public class ArraysDemo1 {
    public static void main(String[] args) {
        // 目标:掌握操作数组的工具类:Arrays的常见方法。
        // 1、返回数组内容:   public static String toString(类型[] a)
        int[] arr = {11, 55, 33, 22, 98};
        //System.out.println(arr);//[I@10f87f48//数组默认返回的是地址
        String result = Arrays.toString(arr);//自动封装好
        System.out.println(result);

        // 2、拷贝数组的内容到一个新的数组,并返回新数组
        // public static 类型[] copyOfRange(类型[] original, int from, int to)
        int arr2[] = Arrays.copyOfRange(arr,1,4);//包前不包后
        System.out.println(Arrays.toString(arr2));

        // 3、给数组扩容。
        // public static 类型[] copyOf(类型[] original, int newLength)
        int[] arr3 = Arrays.copyOf(arr, 10);
        System.out.println(Arrays.toString(arr3));

        // 4、修改数组中每个数据,再存入。
        double[] scores = {99.5, 90, 59.5, 78, 98, 55};
        //需求:为每个分数加分10分
        //第二个参数为接口类型的对象参数,但是接口不能直接new对象,所以需要用匿名内部类
        Arrays.setAll(scores, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int index) {
                return scores[index] + 10;
            }
        });
        System.out.println(Arrays.toString(scores));

        // 5、Arrays类提供的对数组进行排序的操作。
        Arrays.sort(scores);//升序排序(由小到大)
        System.out.println(Arrays.toString(scores));
    }
}

 1.2Arrays的排序

package com.itheima.d1_array;


import java.util.Arrays;
import java.util.Comparator;

public class ArraysDemo2 {
    public static void main(String[] args) {
        // 目标:给存储对象的数组进行排序。
        Student[] students = new Student[4]; // students = [null, null, null, null]
        //                                                   0     1     2     3
        students[0] = new Student("周芷若", 21, '女', 169.3);
        students[1] = new Student("殷素素", 38, '女', 172.2);
        students[2] = new Student("小昭", 19, '女', 168.5);
        students[3] = new Student("张无忌", 23, '男', 183.5);


        // 自定义排序规则方式一:让对象所在的类实现比较规则接口Comparable,重写compareTo方法,来指定比较规则。
//        Arrays.sort(students);

        // 自定义排序规则方式二:sort存在重载的方法,支持自带Comparator比较器对象来直接指定比较规则(优先)
        //  public static <T> void sort(T[] a, Comparator<? super T> c)
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // return o1.getAge() - o2.getAge(); // 升序
                //那么如果要按照身高来进行排序呢?
                //return o1.getHeight() - o2.getHeight();//报错,因为height是double类型,而方法的返回值类型是int
//                if(o1.getHeight() > o2.getHeight()){
//                    return 1;
//                }else if(o1.getHeight() < o2.getHeight()){
//                    return -1;
//                }
//                return 0;
                return Double.compare(o1.getHeight(), o2.getHeight());
            }
        });

        System.out.println(Arrays.toString(students));

    }
}
package com.itheima.d1_array;
// 自定义排序规则方式一:让对象所在的类实现比较规则接口Comparable,重写compareTo方法,来指定比较规则。
public class Student implements Comparable<Student>{
    private String name;
    private int age;
    private char gender;
    private double height;

    public Student() {
    }

    public Student(String name, int age, char gender, double height) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.height = height;
    }

    // 指定大小规则
    // 比较者:this
    // 被比较者:o
    @Override
    public int compareTo(Student o) {
        /**
         * 官方规定:
         * 如果您认为左边大于右边,请返回正整数。
         * 如果您认为左边小于右边,请返回负整数。
         * 如果您认为左边等于右边,请返回0。
         * 只要这么干,默认就是升序排序
         */
//        if(this.age > o.age) {
//            return 1;
//        }else if(this.age < o.age) {
//            return -1;
//        }
//        return 0;
        //return this.age - o.age; // 升序。
        return o.age - this.age; // 降序。
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     * @return gender
     */
    public char getGender() {
        return gender;
    }

    /**
     * 设置
     * @param gender
     */
    public void setGender(char gender) {
        this.gender = gender;
    }

    /**
     * 获取
     * @return height
     */
    public double getHeight() {
        return height;
    }

    /**
     * 设置
     * @param height
     */
    public void setHeight(double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", height=" + height +
                '}' + "\n";
    }


}

 2.JDK8的新特性:Lambda表达式

2.1认识Lambda表达式

package com.itheima.d2_lambda;

public class LambdaTest1 {
    public static void main(String[] args) {
        // 目标:认识Lambda是如何简化匿名内部类的。
        Animal a1 = new Animal() {
            @Override
            public void run() {
                System.out.println("🐅跑的贼快~~~~");
            }
        };
        a1.run();

        // 错误示范:Lambda并不能简化所有匿名内部类的代码。只能简化函数式接口的匿名内部类。
//        Animal a2 = () -> {
//            System.out.println("🐅跑的贼快~~~~");
//        };
//        a2.run();

        Swimming s1 = new Swimming() {
            @Override
            public void swim() {
                System.out.println("学生🏊‍贼溜~~~~");
            }
        };
        s1.swim();

        // Lambda可以简化函数式接口的匿名内部类
        // 可以简化的原因:可以上下文推断出真实的代码形式!
        Swimming s2 = () -> {
                System.out.println("老师🏊‍贼溜~~~~");
        };
        s2.swim();
    }
}

@FunctionalInterface // 函数式接口中有且仅有一个抽象方法
interface Swimming{
    void swim();
}

abstract class Animal{
    public abstract void run();
}

 2.2用Lambda表达式简化代码、省略规则

import com.itheima.d1_array.Student;

import java.util.Arrays;
import java.util.Comparator;
import java.util.function.IntToDoubleFunction;

public class LambdaTest2 {
    public static void main(String[] args) {
        // 目标:掌握Lambda表达式简化常见函数式接口的匿名内部类
        double[] scores = {99.5, 90, 59.5, 78, 98, 55};
        // 需求:为每个分数加分10分。
        Arrays.setAll(scores, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int index) {
                return scores[index] + 10;
            }
        });

        Arrays.setAll(scores, (int index) -> {
                return scores[index] + 10;
        });

        Arrays.setAll(scores, (index) -> {
            return scores[index] + 10;
        });

        Arrays.setAll(scores, index -> {
            return scores[index] + 10;
        });

        Arrays.setAll(scores, index -> scores[index] + 10 );

        System.out.println(Arrays.toString(scores));

        System.out.println("---------------------------------------------------------------------");

        Student[] students = new Student[4]; // students = [null, null, null, null]
        //                                                   0     1     2     3
        students[0] = new Student("周芷若", 21, '女', 169.3);
        students[1] = new Student("殷素素", 38, '女', 172.2);
        students[2] = new Student("小昭", 19, '女', 168.5);
        students[3] = new Student("张无忌", 23, '男', 183.5);

        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return Double.compare(o1.getHeight(), o2.getHeight());
            }
        });

        Arrays.sort(students, (Student o1, Student o2) -> {
                return Double.compare(o1.getHeight(), o2.getHeight());
        });

        Arrays.sort(students, (o1, o2) -> {
            return Double.compare(o1.getHeight(), o2.getHeight());
        });

        Arrays.sort(students, (o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()));

        System.out.println(Arrays.toString(students));
    }
}

3.JDK8的新特性:方法引用(进一步简化Lambda表达式)

3.1 静态方法引用

package com.itheima.d3_method_reference;

public class Student implements Comparable<Student>{
    private String name;
    private int age;
    private char gender;
    private double height;
    
    //在Student类里写一个静态方法,用来通过身高比较
    public static int compareByHeight(Student o1, Student o2){
        return Double.compare(o1.getHeight(), o2.getHeight());
    }

    public Student() {
    }

    public Student(String name, int age, char gender, double height) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.height = height;
    }



    // s1.compareTo(s2)
    // 比较者:s1 == this
    // 被比较者:s2 == o
    @Override
    public int compareTo(Student o) {
        return this.age - o.age; // 升序
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     * @return gender
     */
    public char getGender() {
        return gender;
    }

    /**
     * 设置
     * @param gender
     */
    public void setGender(char gender) {
        this.gender = gender;
    }

    /**
     * 获取
     * @return height
     */
    public double getHeight() {
        return height;
    }

    /**
     * 设置
     * @param height
     */
    public void setHeight(double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", height=" + height +
                '}' + "\n";
    }


}
import java.util.Arrays;

public class Test1 {
    public static void main(String[] args) {
        // 目标:理解静态方法引用。
        Student[] students = new Student[4]; // students = [null, null, null, null]
        students[0] = new Student("周芷若", 21, '女', 169.3);
        students[1] = new Student("殷素素", 38, '女', 172.2);
        students[2] = new Student("小昭", 19, '女', 168.5);
        students[3] = new Student("张无忌", 23, '男', 183.5);

//        Arrays.sort(students, (o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()));//完全够用
//
//        Arrays.sort(students, (o1, o2) -> Student.compareByHeight(o1, o2));

        // 静态方法引用。
        Arrays.sort(students, Student::compareByHeight); // 终极简化代码!

        System.out.println(Arrays.toString(students));

    }
}

3.2 实例方法引用

import java.util.Arrays;

public class Test2 {
    public static void main(String[] args) {
        // 目标:理解实例方法引用。
        Student[] students = new Student[4]; // students = [null, null, null, null]
        students[0] = new Student("周芷若", 21, '女', 169.3);
        students[1] = new Student("殷素素", 38, '女', 172.2);
        students[2] = new Student("小昭", 19, '女', 168.5);
        students[3] = new Student("张无忌", 23, '男', 183.5);

        // Arrays.sort(students, (o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()));

        //要先创建对象
        Test2 t = new Test2();
        // Arrays.sort(students, (o1, o2) -> t.compare(o1, o2));
        Arrays.sort(students, t::compare);
        //还可以更简洁
        //Arrays.sort(students, new Test2()::compare);

        System.out.println(Arrays.toString(students));
    }

    //定义一个对象方法
    public int compare(Student o1, Student o2){
        return Double.compare(o1.getHeight(), o2.getHeight());
    }
}

3.3 特定类型方法的引用

import java.util.Arrays;
import java.util.Comparator;

public class Test3 {
    public static void main(String[] args) {
        // 目标:特定类型的方法引用。
        String[] names = {"dlei", "Angela", "baby", "caocao", "Coach", "曹操" ,"deby", "eason", "andy"};

        // 对他们排序(默认按照首字母编号排序)
        // 拓展(忽略大小写排序)
//        Arrays.sort(names, new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                // o1  Angela
//                // o2  andy
//                return o1.compareToIgnoreCase(o2);
//            }
//        });
//
//        Arrays.sort(names, ( o1,  o2) -> o1.compareToIgnoreCase(o2));

        Arrays.sort(names, String::compareToIgnoreCase);

        System.out.println(Arrays.toString(names));

    }
}

3.4 构造器引用

public class Test4 {
    public static void main(String[] args) {
        // 目标:掌握构造器引用。
//        Create c1 = new Create() {
//            @Override
//            public Car createCar(String name) {
//                return new Car(name);
//            }
//        };
        // Create c1 = name -> new Car(name) ;
        Create c1 = Car::new;
        //硬造场景,实际上Car car = new Car("布加迪威龙");就可以了
        Car car = c1.createCar("布加迪威龙");
        System.out.println(car);
    }
}

@FunctionalInterface // 函数式接口
interface Create{
    //用来创建一个Car对象,Car对象的名字是name
    Car createCar(String name);
}

//硬造场景,没有意义,用来理解语法
//先定义一个Car类
class Car{
    private String name;

    public Car() {
    }

    public Car(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}

4.常见算法

4.1 冒泡

import java.util.Arrays;

public class Demo1 {
    public static void main(String[] args) {
        // 目标:完成冒泡排序的代码实现。
        // 1、定义一个数组
        int[] arr = {5, 2, 3, 1};
        //           0  1  2  3

        // 2、定义一个循环控制冒几轮.
        for (int i = 0; i < arr.length - 1; i++) {
            //  轮数(i)    每轮的次数      j的占位
            //  第一轮0         3          0 1 2
            //  第二轮1         2          0 1
            //  第三轮2         1          0

            // 3、内部循环要控制每轮比较几次
            for (int j = 0; j < arr.length - i - 1; j++) {
                // 4、判断当前位置j是否大于其后一个位置处的数据,若较大,则交换。
                if(arr[j] > arr[j+1]){
                    // 5、定义一个临时变量记住后一个位置处的数据
                    int temp = arr[j+1];
                    // 6、把前一个位置处的数据赋值给后一个位置处
                    arr[j+1] = arr[j];
                    // 7、把后一个位置原来的数据赋值给前一个位置处
                    arr[j] = temp;
                }
            }
        }

        System.out.println(Arrays.toString(arr));
    }
}

4.2 选择排序

package com.itheima.d4_sf;

import java.util.Arrays;

public class Demo2 {
    public static void main(String[] args) {
        // 目标:实现选择排序。
        // 1、定义一个数组
        int[] arr = {5, 1, 3, 2};
        //           0  1  2  3
        // 2、定义一个循环控制选择几轮。
        for (int i = 0; i < arr.length - 1; i++) {
            /**
             轮数(i) 次数    j的占位
             0        3     1  2  3
             1        2     2  3
             2        1     3
             */

            // 3、内部循环控制选择几次。
            for (int j = i + 1; j < arr.length; j++) {
                // 4、判断j对应位置处的数据是否小于当前i位置处的数据,若较小则交换。
                if(arr[i] > arr[j]) {
                    int temp = arr[j];
                    arr[j] = arr[i];
                    arr[i] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

 这种写法会造成数组频繁的交换,性能不好,有没有更优的写法呢?

package com.itheima.d4_sf;

import java.util.Arrays;

public class Demo2_2 {
    public static void main(String[] args) {
        // 目标:实现选择排序。
        // 1、定义一个数组
        int[] arr = {5, 1, 3, 2};
        //           0  1  2  3
        // 2、定义一个循环控制选择几轮。
        for (int i = 0; i < arr.length - 1; i++) {
            /**
             轮数(i) 次数    j的占位
             0        3     1  2  3但是
             1        2     2  3
             2        1     3
             */
           // 定义一个变量记住本轮最小值对应的索引
            int min = i;

            // 3、内部循环控制选择几次。
            for (int j = i + 1; j < arr.length; j++) {
                // 4、判断j对应位置处的数据是否小于当前min位置处的数据,若较小则交换min为j值。
                //也就是找出索引i后面最小的数字与i进行交换,把最小的数字换到i的位置
                if(arr[j] < arr[min]) {
                    min = j;
                }
            }
            //5.如果在本轮中找到了比当前索引i处更小的元素(即min != i),则交换这两个元素。
            if(min != i){
                int temp = arr[i];
                arr[i] = arr[min];
                arr[min] = temp;
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

4.3 二分查找

package com.itheima.d4_sf;

public class Demo3 {
    public static void main(String[] args) {
        // 目标:完成二分查找算法。
        int[] array = {7, 23, 79, 81, 103, 127, 131, 147};
        int index = searchDataIndex(array, 79);
        System.out.println("79的索引是:" + index);

        int index2 = searchDataIndex(array, 179);
        System.out.println("179的索引是:" + index2);
    }

    public static int searchDataIndex(int[] array, int number){
        // array = {7, 23, 79, 81, 103, 127, 131, 147}
        // 1、定义头尾指针
        int left = 0;
        int right = array.length - 1;

        // 2、开始折半查询。
        while (left <= right) {
            // 3、取中间索引
            int middle = (left + right) / 2;
            // 4、判断当前要找的数据,与中间位置处的数据大小情况
            if(number > array[middle]) {
                // 5、往右边找,左边指针更新为 = 中间位置 + 1.
                left = middle + 1;
            }else if(number < array[middle]) {
                // 6、往左边找,右边指针更新为 = 中间位置-1
                right = middle - 1;
            }else {
                return middle;
            }
        }
        return -1;
    }
}

5.正则表达式

5.1 概述

5.2 正则表达式书写规则

预定义字符(只能匹配单个字符) :  \d  \D   \s  \S  \w  \W

在Java中,\是有特殊用途的,一般作为特殊字符使用不能独立存在:\n 代表换行   \t 代表一个空格缩进
 所以在使用预定义字符时 \d 等需要再使用 \ 转义

package com.itheima.d5_regex;

/**
 * 目标:掌握正则表达式的书写规则
 */
public class RegexTest2 {
    public static void main(String[] args) {
        // 1、字符类(只能匹配单个字符)
        System.out.println("a".matches("[abc]"));    // [abc]只能匹配a、b、c
        System.out.println("e".matches("[abcd]")); // false

        System.out.println("d".matches("[^abc]"));   // [^abc] 不能是abc
        System.out.println("a".matches("[^abc]"));  // false

        System.out.println("b".matches("[a-zA-Z]")); // [a-zA-Z] 只能是a-z A-Z的字符
        System.out.println("2".matches("[a-zA-Z]")); // false

        System.out.println("k".matches("[a-z&&[^bc]]")); // : a到z,除了b和c
        System.out.println("b".matches("[a-z&&[^bc]]")); // false

        System.out.println("ab".matches("[a-zA-Z0-9]")); // false 注意:以上带 [内容] 的规则都只能用于匹配单个字符

        // 2、预定义字符(只能匹配单个字符)  .  \d  \D   \s  \S  \w  \W
        System.out.println("徐".matches(".")); // .可以匹配任意字符
        System.out.println("徐徐".matches(".")); // false,因为只能匹配一个字符

        // 在Java中,\是有特殊用途的,一般作为特殊字符使用不能独立存在:\n代表换行 \t代表一个空格缩进
        // \需要再使用\转义
        System.out.println("2".matches("\\d")); // true \d:代表数字0-9  \D:代表非数字
        System.out.println("a".matches("\\d")); // false

        System.out.println(" ".matches("\\s"));   // \s: 代表一个空白字符
        System.out.println("a".matches("\s")); // false

        System.out.println("a".matches("\\S"));  // \S: 代表一个非空白字符
        System.out.println(" ".matches("\\S")); // false

        System.out.println("a".matches("\\w"));  // \w: [a-zA-Z_0-9]
        System.out.println("_".matches("\\w")); // true
        System.out.println("徐".matches("\\w")); // false

        System.out.println("徐".matches("\\W"));  // [^\w]不能是a-zA-Z_0-9
        System.out.println("a".matches("\\W"));  // false

        System.out.println("23232".matches("\\d")); // false 注意:以上预定义字符都只能匹配单个字符。

        // 3、数量词: ?   *   +   {n}   {n, }  {n, m}
        System.out.println("a".matches("\\w?"));   // ? 代表0次或1次
        System.out.println("".matches("\\w?"));    // true
        System.out.println("abc".matches("\\w?")); // false

        System.out.println("abc12".matches("\\w*"));   // * 代表0次或多次
        System.out.println("".matches("\\w*"));        // true
        System.out.println("abc12张".matches("\\w*")); // false

        System.out.println("abc12".matches("\\w+"));   // + 代表1次或多次
        System.out.println("".matches("\\w+"));       // false
        System.out.println("abc12张".matches("\\w+")); // false

        System.out.println("a3c".matches("\\w{3}"));   // {3} 代表要正好是n次
        System.out.println("abcd".matches("\\w{3}"));  // false
        System.out.println("abcd".matches("\\w{3,}"));     // {3,} 代表是>=3次
        System.out.println("ab".matches("\\w{3,}"));     // false
        System.out.println("abcde徐".matches("\\w{3,}"));     // false
        System.out.println("abc232d".matches("\\w{3,9}"));     // {3, 9} 代表是  大于等于3次,小于等于9次

        // 4、其他几个常用的符号:(?i)忽略大小写 、 或:| 、  分组:()
        System.out.println("----------------------------------------------------");
        System.out.println("abc".matches("(?i)abc")); // true
        System.out.println("ABC".matches("(?i)abc")); // true
        System.out.println("aBc".matches("a((?i)b)c")); // true
        System.out.println("ABc".matches("a((?i)b)c")); // false

        // 需求1:要求要么是3个小写字母,要么是3个数字。
        System.out.println("123".matches("(\\d{3})|([a-z]{3})"));//true
        System.out.println("abc".matches("(\\d{3})|([a-z]{3})"));//true
        System.out.println("ab1".matches("(\\d{3})|([a-z]{3})"));//false

        // 需求2:必须是”我爱“开头,中间可以是至少一个”编程“,最后至少是1个”666“
        System.out.println("我爱编程编程666666".matches("我爱(编程)+(666)+"));//true
        System.out.println("我爱编程编程6666666".matches("我爱(编程)+(666)+"));//false一定要3个666
    }
}

 5.3 正则表达式案例

需求:校验用户输入的电话、邮箱、时间是否合法

shift + F6 给相同的名称重新命名

package com.itheima.d5_regex;

import java.util.Scanner;

public class RegexTest3 {
    public static void main(String[] args) {
        // 目标:使用所学的正则表达式来校验数据的合法性。
        //checkEmail();
         checkPhone();
    }

    public static void checkPhone(){
        while (true) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请您输入手机号码:");
            String phone = sc.next();
            if(phone.matches("1[3-9]\\d{9}")) {
                System.out.println("手机号码合法,录入成功!");
                break;
            }else {
                System.out.println("您输入的手机号码有毛病!请重新输入!");
            }
        }
    }

    public static void checkEmail(){
        while (true) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请您输入邮箱:");
            String email = sc.next();
            // dlei0009@163.com
            // 5423253@qq.com
            // xulei2@itcast.com.cn
            if(email.matches("\\w{2,30}@\\w{2,20}(\\.\\w{2,30}){1,2}")) {
                System.out.println("邮箱合法,录入成功!");
                break;
            }else {
                System.out.println("您输入的邮箱有毛病!请重新输入!");
            }
        }
    }

}

5.4 正则爬取内容

第一个案例:

package com.itheima.d5_regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest4 {
    public static void main(String[] args) {
        // 目标:了解使用正则表达式去文本中爬取想要的信息。
        String data = "来黑马程序员学习Java,\n" +
                "电话:18512516758,18512508907\n" +
                "或者联系邮箱: boniu@itcast.cn\n" +
                "座机电话:01036517895,010-98951256\n" +
                "邮箱:bozai@itcast.cn,\n" +
                "邮箱2:dlei0009@163.com,\n" +
                "热线电话:400-618-9090 ,400-618-4000,\n" +
                "4006184000,4006189090\n";

        // 需求:从中间爬取出邮箱 手机号码 座机号码 400号码。
        // 1、定义爬取规则对象,封装要爬取的格式。
        //这是官方规定的格式去编译我们所写的爬取规则,来得到一个爬取规则对象
        Pattern pattern = Pattern.compile("(\\w{2,30}@\\w{2,20}(\\.\\w{2,20}){1,2})|(1[3-9]\\d{9})" +
                "|(0\\d{2,6}-?[1-9]\\d{3,10})|(400-?[1-9]\\d{2,6}-?[1-9]\\d{2,6})");

        // 2、通过匹配规则对象pattern与内容data建立联系得到一个匹配器对象
        //匹配器对象可以拿到匹配规则pattern去提供的数据data中爬取内容
        Matcher matcher = pattern.matcher(data);

        // 3、使用匹配器对象,开始爬取内容。
        //matcher.find()的返回值类型是boolean,如果返回为true就说明爬取到符合规则的内容
        while (matcher.find()){
            String info = matcher.group();
            System.out.println(info);
        }
    }
}

第二个案例:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest5 {
    public static void main(String[] args) {
        // 目标:了解使用正则表达式去文本中爬取想要的信息。(分组爬取)
        String data = "来黑马程序员学习Java,\n" +
                "电话:18512516758,18512508907\n" +
                "或者联系邮箱: boniu@itcast.cn\n" +
                "座机电话:01036517895,010-98951256\n" +
                "邮箱:bozai@itcast.cn,\n" +
                "邮箱2:dlei0009@163.com,\n" +
                "热线电话:400-618-9090 ,400-618-4000,\n" +
                "4006184000,4006189090\n";

        // 1、指定爬取规则对象:设置匹配规则。
        //用分组爬取,把邮箱前面的部分括起来代表第一组
        Pattern p = Pattern.compile("(\\w{2,30})@\\w{2,20}(\\.\\w{2,20}){1,2}");
        // 2、让内容和爬取规则建立关系,得到一个匹配器对象。
        Matcher matcher = p.matcher(data);
        // 3、开始使用匹配器对象,开始爬取内容
        while (matcher.find()) {
            // 把爬到的信息提取出来
            String rs = matcher.group(1); // 只要爬取出来的邮箱中的第一组括号的内容。
            System.out.println(rs);
        }
    }
}

 第三个案例:

 

package com.itheima.d5_regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest6 {
    public static void main(String[] args) {
        // 目标:了解使用正则表达式去文本中爬取想要的信息。(了解)
        String data = "欢迎张全蛋光临本系统!他删库并跑路欢迎李二狗子光临本系统!" +
                " 欢迎马六子光临本系统!它浏览了很多好看的照片!欢迎夏洛光临本系统!他在六点钟送出了一个嘉年华!" ;

        // 1、指定爬取规则对象:设置匹配规则。
        //(.+)代表中间的名字可以是任意个
//         String regex1 = "欢迎(.+)光临"; // 贪婪匹配! 最大范围匹配:从第一个欢迎匹配到最后一个光临
        String regex2 = "欢迎(.+?)光临"; // 非贪婪匹配 最小范围匹配(规定,也可以理解为?代表0或1次)

        Pattern p = Pattern.compile(regex2);
        // 2、让内容和爬取规则建立关系,得到一个匹配器对象。
        Matcher matcher = p.matcher(data);
        // 3、开始使用匹配器对象,开始爬取内容
        while (matcher.find()) {
            // 把爬到的信息提取出来
            String rs = matcher.group(1); // 我只要爬取内容中的第一组()内容
            System.out.println(rs);
        }
    }
}

 组的编号规则:组号是按照左括号出现的顺序来确定的,从1开始计数

特殊组号0:组号0代表的是整个正则表达式所匹配的内容,组0对应的就是“欢迎张全蛋光临”这样完整的内容

而组1也就是(.+?),他匹配的是两个关键词之间的任意字符,如“张全蛋”就是组1匹配的内容,会把所有满足条件的内容都输出

5.5 搜索、分割

import java.util.Arrays;

/**
 * 目标:了解使用正则表达式做搜索替换,内容分割。
 */
public class RegexTest7 {
    public static void main(String[] args) {
        // 1、public String replaceAll(String regex , String newStr):按照正则表达式匹配的内容进行替换
        // 需求1:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中间的非中文字符替换成 “-”
        String s1 = "古力娜扎ai8888迪丽热巴99fafas9aa5566马尔扎哈fbbADFFfsfs42425卡尔扎巴";
        //\w+代表一次或多次英文字母,数字或下划线
        String result = s1.replaceAll("\\w+", "-");
        System.out.println(result);


        // 2、public String[] split(String regex):按照正则表达式匹配的内容进行分割字符串,反回一个字符串数组。
        // 需求1:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中的人名获取出来。
        String[] names = s1.split("\\w+");
        for (int i = 0; i < names.length; i++) {
            System.out.println(names[i]);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值