正则表达式(Regular Expression)教程

正则表达式简介

  • 为什么需要正则表达式
    • 文本的复杂处理
  • 正则表达式的优势和用途
    • 一种强大而灵活的文本处理工具;
    • 大部分编程语言、数据库、文本编辑器、开发环境都支持正则表达式
  • 正则表达式定义:
    • 正如它的名字一样是描述了一个规则,通过这个规则可以匹配一类字符串。
    • 学习正则表达式很大程度上就是学习正则表达式的语法规则
  • 开发中使用正则表达式的流程:
    • 分析所要匹配的数据,写出测试用的典型数据
    • 在工具软件中进行匹配测试
    • 在程序中调用通过测试的正则表达式

正则表达式语法

普通字符

  • 字母、数字、汉字、下划线、以及没有特殊定义的标点符号,都是“普通字符”。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。

简单的转义字符

转义字符含义
\n换行符
\t制表符
\\代表\本身
\^,\$,\.,\(,\),\{,\},\?,\+,\*,|,\[,\]匹配这些字符本身

标准字符集合

  • 能够与“多种字符”匹配的表达式
  • 注意区分大小写,大写是相反的意思
符号含义
\d任意一个数字,0~9中任意的一个
\w任意一个字母或数字或下划线,依旧是A~Z,a~z,0~9, _中任意一个
\s包括空格、制表符、换行符和空白字符的其中任何一个
.小数点可以匹配除了”\n”以外的任意一个字符,如果要匹配包括”\n”在内的所有字符,一般用[\s\S]

自定义字符集合:

  • [] 方括号匹配方式,能够匹配方括号中任意一个字符
表达式含义
[abc4@]匹配”a”或”b”或”4”或”@”
[^abc]匹配”a”,”b”,”c”之外的任意一个字符
[f-k]匹配”f”~”k”之间的任意一个字母
[^A-F0-3]匹配”A”~”F”,”0”~”3”之外的任意一个字符

- 正则表达式的特殊符号,被包含到中括号中,则失去了特殊意义,除了^,- 之外
- 标准字符集合,除了小数点外,如果被包含于中括号,自定义字符集合将包含该集合。比如:[\d.-+]将匹配:数字、小数点、+、-

量词(Quantifier)

  • 修饰匹配次数的特殊符号
表达式含义
{n}表达式重复n次
{m,n}表达式至少重复m次,最多重复n次
{m,}表达式至少重复m次
?匹配表达式0次或者1次,相当于{0,1}
+表达式至少出现1次,相当于{1,}
*表达式不出现或者出现任意次,相当于{0,}

- 匹配次数中的贪婪模式(匹配的字符越多越好,默认!)
- 匹配次数中的非贪婪模式(匹配的字符越少越好,修饰匹配次数的特殊符号后再加上一个?

字符边界

  • (本组标记匹配的不是字符而是位置,符合某种条件的位置)
符号含义
^与字符串开始的地方匹配
$与字符串结束的地方匹配
\b匹配一个单词边界

- \b 匹配这样一个位置:前面的字符和后面的字符不全是\w

选择符和分组

表达式作用
| 分支结构左右两边表达式之间“或”关系,匹配左边或者右边
() 捕获组(1)在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰.(2)取匹配结果的时候,括号中的表达式匹配到的内容可以背单独的到(3)每一对括号会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。捕获元素编号为零的第一个捕获使由整个正则表达式模式匹配的文本
?:Expression 非捕获组一些表达式中,不得不使用(),但又不需要保存()中的表达式匹配的内容,这是可以使用非捕获组来抵消使用()带来的副作用

- 反向引用(\nnn)每一对() 都会分配一个编号,使用() 的捕获根据左括号的顺序从1开始自动编号。通过反向引用,可以对分组已捕获的字符串进行引用。

预搜索(零宽断言)

  • 只进行子表达式的匹配,匹配内容不计入最终的匹配结果,是零宽度
  • 这个位置应该符合某个条件。判断当前位置的前后字符,是否符合制定的条件,但不匹配前后的字符。是对位置的匹配
  • 正则表达式匹配过程中,如果子表达式匹配到的是字符内容,而非位置,并被保存到最终的匹配结果中,那么就认为这个子表达式是占有字符的;如果子表达式匹配到的仅仅是位置,活着匹配的内容并不保存到最终的匹配结果中,那么就认为这个子表达式是零宽度的。占有字符还是零宽度,是针对匹配的内容是否保存到最终的匹配结果中而言的。
表达式含义
(?=exp)断言自身出现的位置的后面能够匹配表达式exp
(?<=exp)断言自身出现的位置的前面能够匹配表达式exp
(?!exp)断言此位置的后面不能匹配表达式exp
(?<!exp)断言次位置的前面不能匹配表达式exp

正则表达式的匹配模式

  • IGNORECASE忽略大小写模式
    • 匹配时忽略大小写
    • 默认情况下,正则表达式是要区分大小写的
  • SINGLELINE 单行模式
    • 整个文本看作一个字符串,只有一个开头,一个结尾
    • 使小数点. 可以匹配包含换行符(\n)在内的任意字符。
  • MULTILINE 多行模式
    • 每行都是一个字符串,都有开头和结尾。
    • 在指定了MULTILINE之后,如果需要仅匹配字符串开始和结束位置,可以使用\A\Z

常用正则表达式列表

含义表达式
匹配中文字符[\u4e00-\u9fa5]
匹配空白行\n\s*\r
匹配HTML标记<(\S*?)[^>]*>.*?</\1>|<.*?/>
匹配首尾空白字符^\s*|\s*$
匹配Email地址\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配网址URL[a-zA-Z]+://[^\s]*
匹配国内电话号码\d{3}-\d{8}|\d{4}-\d{7}
匹配腾讯QQ号码[1-9][0-9]{4,}
匹配中国邮编[1-9]\d{5}(?!\d)
匹配身份证号码\d{15}|\d{18}
匹配ip地址\d+\.\d+\.\d+\.\d+

在编辑器中使用正则表达式查找

  • 一般在各种IDE或文本编辑器都支持正则表达式的查找(Ctrl+F或Cmd+F 调出查找,勾选正则查找)
  • Sublime Text
    这里写图片描述
  • Intel IDEA
    这里写图片描述

爬虫原理代码

package com.coderbean.regex.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 网络爬虫取链接小Demo
 *
 * Created by Chang on 15/10/7.
 */
public class WebSpiderTest {
    public static void main(String[] args) {
        String destStr = getURLContent("http://www.163.com","gbk");
//        System.out.println(destStr);
//        //取到的是超链接的整个内容
//        Pattern pattern = Pattern.compile("<a[\\s\\S]+?</a>");  
        String regexStr = "href=\"(http://.+?)\"";

        List<String> list = getMatherSubstrs(destStr,regexStr);
        for(String temp:list){
            System.out.println(temp);
        }

    }
    public static List<String> getMatherSubstrs(String destStr,String regexStr){

        List<String> list = new ArrayList<String>();
        Pattern pattern = Pattern.compile(regexStr);
        Matcher matcher = pattern.matcher(destStr);

        while(matcher.find()){
            list.add(matcher.group(1));
        }
        return list;
    }
    /**
     * 获得URL对应的网页的内容
     * @param urlStr
     * @return
     */
    public static String getURLContent(String urlStr, String charset){
        try {
            URL url = new URL(urlStr);
            StringBuilder sb = new StringBuilder();
            BufferedReader bufferedReader = new BufferedReader(
                    new InputStreamReader(url.openStream(), Charset.forName(charset)));
            String temp = "";
            while(null!=(temp = bufferedReader.readLine())) {
                sb.append(temp);
                sb.append('\n');
            }
            return sb.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值