正则表达式入门知识+用它实现在一个网页中获取所有的链接地址

    xiaoxiao2022-06-22  24

    大家可以加群一起学习:688160561

    概念:正则表达式是一种计算机科学的概念、它通常用来检索和替换那些符合规则的文本或者字符串。现在很多的程序设计语言计都支持利用正则表达式来进行字符串的操作,有java、c++、python、javascript、perl、php等。

    作用:

     1 给定的字符串是否符合正则表达式

     2 通过正则表达式可以从字符串中获取我们想要的特定部分

    规则:

    开始与结束:^、$

    表示匹配个数:+(1次以上)、?(0或者1次)、|、< >、(注:前面四个元字符并不是所有的软件都支持)*、{n}、{n,}、{n,m}、\p{P}(javascript不支持)、.点(除\n\r外单个字符) *(任意次)

    表示匹配范围:[xyz]、[^xyz]、[a-z]、[^a-z]

    特殊字符时用:\    "\\d"

    大小写:(大写表示否,小写表示是) \b (单词边界)\B  \d (数字)\D \s (不可见字符)\S \w (包含下划线字符)\W

    不可见字符:\f、\r、\n、 \t、\v

    组合:\cx  \xn(十六进制 ascII编码) \num、\n、\nm、\nml(八进制编码)、\un(十六进制unicode编码)中文

    非获取匹配:(?:pattern)、(?=pattern)(匹配pattern的前面部分)、(?!pattern)、(?<=pattern)(匹配pattern的后面部分)、(?<!pattern)(否定)

    几个例子快速认识:

    1.验证用户名和密码:("^[a-zA-Z]\w{5,15}$")正确格式:"[A-Z][a-z]_[0-9]"组成,并且第一个字必须为字母6~16位; 2.验证电话号码:("^(\\d{3,4}-)\\d{7,8}$")正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx; 3.验证手机号码:"^1[3|4|5|7|8][0-9]\\d{8}$"; 4.验证身份证号(15位或18位数字):"\\d{14}[[0-9],0-9xX]"; 5.验证Email地址:("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");

    正则引擎:

    NFA引擎(以表达式为准,容易操作,但速度慢,,为了匹配正则表达式的所有可能的扩展,可能对相同字符匹配多次,所以采用贪婪的回溯算法),java python perl 

    DFA引擎(以文本为准,速度较快,但不好控制,在线性状态下执行,不要求回溯)。awk grep mysql程序都采用这个引擎。

    JAVA类库java.util.regex包

    Pattern类与matcher类

    pattern类

    compile(String regx)  参数正则表达式  返回值  pattern对象  功能

    split(String str)  参数字符串  返回值string [] 返回被regx分隔的字符串数组

    matches(String regex,String   str) 静态方法,返回boolean 用于快速匹配,只匹配一次,匹配全部字符串

    matcher(String str)返回matcher类的对象 由pattern类对象调用

    matcher类

    pattern()返回pattern类对象,也就是该对象创建matcher类对象的

    matches()用于匹配整个字符串 成功返回true

    lookAt()对前面的字符串匹配 成功返回true

    find()对字符串进行匹配,匹配到的子字符串可以在任何位置。成功返回true

    start()返回匹配到的子字符串在字符串中的索引位置

    end()返回匹配到的子字符串的最后一个字符在字符串中的索引位置

    group()返回匹配到的子字符串

    还有重载它们的方法start(i)、end(i)、group(i)用于分组操作,groupCount()返回分组数  即有多少个()被匹配了

    注意:每次执行一次start end group的值都会发生变化的 ,并且用它们之前一定要确定已经匹配成功了,即find lookAt matches方法返回成功true,否则发生错误java.lang.IllegalStateException。

    应用:

    public class TCPSever { /** http协议结构 * http请求包话三个部分: * 1、请求行 * 组成:method request-url http-version crlf * get / www.baidu.com http/1.1 \r\n * 2、消息报头 * 类型: * HOST: WWW.baidu.com \r\n * 3、请求正文 * \r\n * http响应由三部分组成 * 1、状态行 * 2、消息报头 * 3、响应正文 * */ public String getContent(){ String str=null; try { // //创建客户端对象 System.out.println("开始创建客户端对象……"); Socket client=new Socket("www.baidu.com",80); //创建输入、输出流对象 InputStream in=client.getInputStream(); OutputStream out=client.getOutputStream(); //字节流转为字符流,再把字符流写入缓冲区 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter( out)); BufferedReader br = new BufferedReader(new InputStreamReader( in)); bw.write("GET / HTTP/1.1\r\n"); bw.write("Host: www.baidu.com\r\n"); bw.write("\r\n"); bw.flush(); String line = null; StringBuffer bf=new StringBuffer(4000); int sum=0; System.out.println("从百度中请求到的数据是:"); while(true){ if((line=br.readLine())!=null) { bf.append(line+"\n\r"); sum++; } else break; } //把缓冲区的字符串转为字符串 String str1=new String(bf); //修改编码,解码,因为gbk是eclipse默认的编码,改为UFT-8,符合服务器那边要求 //当然我这样做为了方便大家了解编码解码过程,不然就直接在while循环输出了,可以从 //服务器那边响应报头知道文本的编码格式为UTF-8 str=new String(str1.getBytes("gbk"),"UTF-8"); // System.out.print("有"+sum+"行\r\n"+"缓冲区长度"+bf.length()+"\r\n"+str); /* * */ br.close(); bw.close(); in.close(); out.close(); client.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return str; } public void getHttp(String regex,String str){ //利用pattern和matcher类实现 System.out.println(str); Pattern pattern=Pattern.compile(regex); Matcher matcher=pattern.matcher(str); int sum=0; //没必要用这个List,我只是为了测试 List str1=new Vector(); while(matcher.find()){ sum++; str1.add(matcher.group()); System.out.println("第"+sum+"个"+matcher.group()+" "+"起始位置"+matcher.start()+" "+"结束位置"+matcher.end()); } //System.out.println(s); } public static void main(String args[]){ TCPSever tcp=new TCPSever(); //这个http响应返回的内容当做一个字符串,所以别用^或者$ //字符串 String str="href=\"(http://|//)[^\\s]*\""; String content=tcp.getContent(); tcp.getHttp(str,content); } } 运行结果:

    javascript

    javascript里通过创建new REgExp(pattern,attributes)对象来调用它对应的函数和属性来支持正则表达式。

    属性:

    global全局匹配 匹配多次

    ignoreCase忽略大小写

    lastIndex 执行一次test    移动到匹配位置并加+ 不够从零开始

    multiline 忽略^ $执行多行首尾

    source

    方法:

    compile 重新编译正则表达式

    exec检索字符串指定的值,并返回找到的值和确定它的位置

    test 检索字符串指定的值,找到返回true

    String对象支持正则表达式的方法

    search(regex)检索与正则表达式匹配的值  参数:可以是字符串中的匹配的子字符串或中RegExp对象  返回第一个匹配的子字符串在字符串中的索引位置,它忽略g和lastIndex属性,也就是它不执行全局匹配和总是从头开始匹配

    match( regex)找到一个或者多个与正则表达式匹配的值   匹配返回值不匹配返回null  /g全局匹配  返回与它匹配的所有子字符串。

    replace (regex,String str)替换与正则表达式匹配的字符串    即用str替换满足用正则表达式匹配到的子字符串

    split(string str,[len])把字符串分割成字符串数组   str可以是字符或者是正则表达式/^\\d+/(不是RegExp对象),[len]表示可选,是限定返回数组的长度

    注意:如果正则表达式与字符串函数同样能达到效果就用字符串函数,效率高。

    应用

    数据库

    以后有时间再补上。。。

    oracle

    mysql

    mongdb

    sql server 2005

    转载请注明原文地址: https://ju.6miu.com/read-1122698.html

    最新回复(0)