JAVA之旅(三十四)——自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫

JAVA之旅(三十四)——自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫


我们接着来说网络编程,TCP

一.自定义服务端

我们直接写一个服务端,让本机去连接,可以看到什么样的效果

package com.lgl.socket;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class BrowserServer {

    //http://192.168.1.103:11000/

    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(11000);
            Socket s = ss.accept();
            System.out.println(s.getInetAddress().getHostName() + ":" + s.getInetAddress().getHostAddress());
            PrintWriter out = new PrintWriter(s.getOutputStream(), true);
            out.println("Hello Client");
            s.close();
            ss.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

我们运行了之后直接访问http://192.168.1.103:11000/就知道什么效果

我们控制台也打印出我们的地址来了

比较有意思的是,既然是网页打开,那么他是支持html的,我们来输出这句

out.println("<font color='red' size='30'>Hello Client");

你就可以看到

二.URLConnection

先看URL的用法

package com.lgl.socket;

import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo {

    public static void main(String[] args) {
        try {
            URL url = new URL("http://192.168.1.102/myweb/test.html?name=zhangsan&age=18");
            // 协议
            System.out.println(url.getProtocol());
            // 主机
            System.out.println(url.getHost());
            // 端口
            System.out.println(url.getPort());
            // 路径
            System.out.println(url.getPath());
            // 查询部
            System.out.println(url.getQuery());
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

得到的结果

继续来看

// 返回一个url连接对象
URLConnection openConnection = url.openConnection();
System.out.println(openConnection);
InputStream inputStream = openConnection.getInputStream();
byte[] buf = new byte[1024];
int len = inputStream.read(buf);
System.out.println(new String(buf, 0, len));

其实可以读取流,我们从流中拿到我们想要的东西

三.正则表达式特点

正则表达式:你可以理解为符合一定规则的表达式,正则我们虽然用的不多,但是确实比较适用的,我们主要来看他的做用

  • 专门操作字符串

我们直接来看下使用方法

我们现在有一个需求

  • 对QQ号码进行效验,要求5-15位,不能开头,只能是数字

先看一下我们的传统方式是怎么去计算的

public class Test {

    public static void main(String[] args) {
        /**
         * 对QQ号码进行效验,要求5-15位,不能开头,只能是数字
         */
        String qq = "11299923";
        int len = qq.length();
        // 长度
        if (len > 5 && len <= 15) {
            // 不能0开头
            if (!qq.startsWith("0")) {
                // 全部是数字
                char[] charArray = qq.toCharArray();
                boolean flag = false;
                for (int i = 0; i < charArray.length; i++) {
                    if (!(charArray[i] >= '0' && charArray[i] <= '9')) {
                        flag = true;
                        break;
                    }
                }
                if (flag) {
                    System.err.println("QQ:" + qq);
                } else {
                    System.out.println("非纯数字");
                }
            } else {
                System.out.println("0开头不符合规范");
            }
        } else {
            System.out.println("QQ长度有问题");
        }
    }
}

这是一件非常麻烦的事情的,而我们来看下正则表达式,是怎么表示的

public class Test1 {

    public static void main(String[] args) {

        String qq = "789152";
        /**
         * 我只要告诉你对与错就行
         */
        String regex = "[1-9][0-9]{4,14}";
        boolean flag = qq.matches(regex);
        if (flag) {
            System.out.println("QQ:" + qq);
        } else {
            System.out.println("错误");
        }
    }
}

非常的强大,只要几行代码就可以显示,牛啊,这符号定义我们稍后解答

四.匹配

正则很厉害,我们来看下他的作用

  • 特点:用一些特定的符号来表示一些代码操作,这样就简化了书写,学习正则表达式就是用来学习一些特殊符号的使用

  • 1.匹配:matches

我们来看下这段代码

        String str = "c";
        /**
         * 这个字符串只能是bcd中的其中一个,而且只能是一个字符
         */
        String reg = "[bcd]";
        boolean flag = str.matches(reg);
        System.out.println(flag);

含义理解清楚,其实就比较顺眼了一点点了,我们继续

        /**
         * 这个字符的第二位是a-z就行
         */
        String reg1 = "[bcd][a-z]";
        boolean flag1 = str.matches(reg);
        System.out.println(flag1);

到现在是否是有点概念?我们继续,如果我现在想我第一个是个字母第二个是个数字,该怎么去拼?

    String reg2 = "[a-zA-Z][0-9]";
    boolean flag2 = str.matches(reg2);
    System.out.println(flag2);

大致的讲解一下,因为我也不是很熟,嘿嘿

五.切割

这个切割,在string也是一个切割split,而我们的正则,也是有的,我们继续看

public class Test2 {

    public static void main(String[] args) {

        String str = "zhangsan,lisi,wangwu";
        String reg = ",";
        String[] split = str.split(reg);
        for (String s : split) {
            System.out.println(s);
        }
    }
}

我们输出

六.替换

正则表达式就是string的操作,我们看下替换

public class Test2 {

    public static void main(String[] args) {
        // 将数字连续超过五个替换成#号
        replaceAll("fwfsda777777fs74666677s", "\\d{5,}", "#");
    }

    public static void replaceAll(String str, String reg, String newStr) {
        str = str.replaceAll(reg, newStr);
        System.out.println(str);
    }
}

得到的结果

七.获取

  • 1.将正则表达式封装成对象
  • 2.让正则表达式和要操作的对象进行关联
  • 3.关联后,获取正则匹配引擎
  • 4.通过引擎对符合规则的子串进行操作,比如取出
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test2 {

    public static void main(String[] args) {

        String string  = " hello java android c cc ccc cccc ccccc";
        //test
        String reg = "[a-z]";

        //将规则封装成对象
        Pattern p = Pattern.compile(reg);
        //让正则对象和要作用的字符串相关联,获取匹配器对象
        Matcher matcher = p.matcher(string);
        System.out.println(matcher.matches());
    }

}

体现了一个模式而已,我们可用通过这个模式去获取字符串

八.网页爬虫

爬虫我们再熟悉不过了,也俗称蜘蛛,其实就是获取一些数据罢了,我们也是可以用到我们正则中的获取功能的

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test2 {

    public static void main(String[] args) {

    }

    /**
     * 获取指定文档中的邮箱地址
     */
    public static void getEmail() {
        try {
            BufferedReader bufr = new BufferedReader(
                    new FileReader("email.txt"));
            String line = null;
            String emailreg = "\\w+@\\w+(\\.\\w+)+";
            Pattern p = Pattern.compile(emailreg);
            while ((line = bufr.readLine()) != null) {
                System.out.println(line);
                // 判断邮箱
                Matcher m = p.matcher(line);
                while (m.find()) {
                    System.out.println(m.group());
                    // 这样就拿到所有的邮箱了
                }
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

这样我们的所有邮箱号码就拿到了,当然,这只是一个简单的爬虫概念,爬虫博大精深,我们要学习的话还是要系统的了解一下才好!!!

好的,我们的java之旅也到这里over了,我们本篇也结束了

时间: 2024-11-02 07:19:54

JAVA之旅(三十四)——自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫的相关文章

JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是class对象 我们在上节验证了同步函数的锁是this,但是对于静态同步函数,你又知道多少呢? 我们做一个这样的小实验,我们给show方法加上static关键字去修饰 private static synchronized void show() { if (tick > 0) { try { Thread

JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码

JAVA之旅(三十)--打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码 三十篇了,又是一个阳光明媚的周末,一个又一个的周末,周而复始,不断学习,前方的路你可曾看见?随我一起走进技术的世界,流连忘返吧! 一.打印流PrintWriter 打印流有PrintWriter和PrintStream,他的特点可以直接操作输入流还有文件 该流提供了打印方法,可以将各种数据类型原样打印 file对象

JAVA之旅(十)——异常的概述,Try-Catch,异常声明Throws,多异常处理,自定义异常,Throw和Throws的区别

JAVA之旅(十)--异常的概述,Try-Catch,异常声明Throws,多异常处理,自定义异常,Throw和Throws的区别 不知不觉,JAVA之旅这个系列已经更新到第十篇了,感觉如梦如幻,时间过得很快,转眼一个月就这样过去了,我们不多说,继续我们的JAVA之旅 一.异常的概述 异常算是程序中一个比较重要的环节了,我们首先来看一下异常的体系,我们举一个小例子,定义一个除法方法 //公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方

JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口

JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一.Thread 如何在自定义的代码中,自定义一个线程呢? 我们查看API文档,我们要启动一个线程,先实现一个子类, package com.lgl.hellojava; public class MyThread extends Thread { @Override public void run()

java程序员三至四年的工作经验,应该具备那些技术、能力呢?

问题描述 参加工作这么多年,回头认真想想感觉啥也不懂似的.总是关注招聘网站,对于三至四年工作经验的职位要求,从而学习.充实,但有时候会自问一下,java程序员三至四年的工作经验,应该具备那些技术.能力呢? 解决方案 解决方案二:"几年的工作经验要求"所衡量的技术只是其中的一部分,技术不可能没有差距和区别,毕竟大家做的项目都有差距,侧重点就有区别的.当然也有共性的,举例如下:1.语言要求:精通java,j2ee2.框架要求:springMVC,mybatis或类似框架开发经验3.页面技术

JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止

JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们解释过来应该是生产一个,消费一个,的意思,具体我们通过例子来说 package com.lgl.hellojava; //公共的 类 类名 public class HelloJJAVA { public static void main(String[] args) { /** * 生产者和消费者

JAVA之旅(十八)——基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用

JAVA之旅(十八)--基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用 JAVA把完事万物都定义为对象,而我们想使用数据类型也是可以引用的 一.基本数据类型的对象包装类 左为基本数据类型,又为引用数据类型 byte Byte int Integer long Long boolean Booleab float Float double Double char Character 我们拿Integer来举例子 //整

Sql Server之旅——第十四站 深入的探讨锁机制

原文:Sql Server之旅--第十四站 深入的探讨锁机制 上一篇我只是做了一个堆表让大家初步的认识到锁的痉挛状态,但是在现实世界上并没有这么简单的事情,起码我的表不会没有索引对吧,,,还 有就是我的表一定会有很多的连接过来,10:1的读写,很多码农可能都会遇到类似神乎其神的死锁,卡住,读不出来,插不进入等等神仙的事情导致性 能低下,这篇我们一起来探讨下.   一: 当select遇到性能低下的update会怎么样? 1. 还是使用原始的person表,插入6条数据,由于是4000字节,所以两

Henry的VB.NET之旅(十四)—动态关联事件与处理程序

程序|动态 Henry的VB.NET之旅(十四)-动态关联事件与处理程序 韩睿 "要解释新的事件处理程序的方法,我们需要先说几个重要的问题."大李开始严肃起来,我也只得挪动一下身子,表现出正襟危坐的架势. "我们首先讨论一下事件是怎么产生的.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互,例如鼠标单击引起的,也可能是由某些其他的程序逻辑触发的.引发事件的对象叫做事件发送方(啊,听到这,Henry突然明白了事件处理程序中的第一个参量为什么叫Sender了,就