正则表达式笔记

正则表达式

普通字符:

所谓的普通字符指的是字母、数字、汉字、下划线、没有特殊含义的标点符号

\n代表换行符

\t代表制表符

\\代表转义符\本身

\^,\$,\{,\},\(,\),\?,\+,\*,\|,\[,\]代表这些字符本身

标准字符集合

所谓的标准字符集合指的是能够与多种字符匹配的表达式

尤其注意下面的大小写,大写和小写是互为相反的关系

\d匹配任意数字,也就是0-9中任意一个

\w匹配任意一个字母、数字、下划线,也就是A-Z,a-z,0-9,_中任意一个

\s匹配空格、制表符、换行符等空白字符中任意一个

.匹配任意一个字符,如果要匹配包括\n在内的所有字符,一般用[\s\S]

自定义字符集合

[ab5@]匹配"a"或"b"或"5"或"@"

[^abc]匹配 a b c 之外的任意字符

[f-k]匹配 f - k 之间的任意一个字母

[^A-F0-3]匹配 A - F,0 - 3 之外的任意一个字符

正则表达式的特殊符合,被包含到中括号中,就失去了特殊的意义,除了^,-之外

标准字符集合,除小数点外,如果被包含于中括号,自定义字符集合将包含该集合

[\d.\-+]匹配数字、小数点、+、-

量词

{n}表达式至少重复n次

{m,n}表达式至少重复 m 次,最多重复 n 次

{m,}表达式至少重复m次

?表达式重复 0 次或者 1 次,相当于{0,1}

+表达式至少出现 1 次,相当于{1,}

*表达式不出现或出现任意次,相当于{0,}

贪婪模式{m,n}中默认的匹配情况是匹配字符越多越好,这就是所谓的贪婪模式

非贪婪模式修饰匹配次数的特殊符号加上?号,比如上面{m,n},可以表示为{m,n}?,这样匹配的字符越少越好

字符边界(零宽匹配)

^匹配字符串开始的地方

$匹配字符串结束的地方

\b匹配一个单词边界,边界的定义:前面字符和后面字符不全是\w

\b举例:xiao\b

xiao xiao123	xiao	xiao_wdsfw

这里要明确匹配的是位置而不是任何的字符可以匹配的第一个xiao、第三个xiao;第二个因为o和1都是\w所以不能匹配,第四个也是同理

匹配模式

IGNORECASE 忽略大小写模式匹配时忽略大小写,默认情况下正则是区分大小写的

SINGLELINE 单行模式整个文本看作一个字符串,只有一个开头和结尾

MULTILINE 多行模式每行都是一个字符串,都有开头和结尾,如果在这个模式下仅需匹配字符串的开始和结束位置,可以用\A 和 \Z

选择符和分组

|左右两边是的关系

()捕获组

//在被修饰的匹配次数的时候,括号中的表达式可以作为整体被修饰

//取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到

//每一对括号会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动的编号,捕获元素编号为零的第一个捕获是由整个正则表达式模式匹配的文本

(?:xxxxxxx)在某些表达式中,不得不使用到(),但又不需要保存()中子表达式匹配的内容,主要原因是占内存,所以可以采用?:方式来声明

反向引用

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

具体java中的例子

/**
* 正则表达式test
*/
public class test01 {

   public static final String P_UNCAP = "(?:\\d{4})-((\\d{2})-(\\d{2}))";
   public static final String DATE_STRING = "2017-04-25";

   public static void main(String[] args) {

       Pattern pattern = Pattern.compile(P_UNCAP);
       Matcher matcher = pattern.matcher(DATE_STRING);
       matcher.find();
       System.out.printf("\nmatcher.group(0) value:%s", matcher.group(0));
       System.out.printf("\nmatcher.group(1) value:%s", matcher.group(1));
       System.out.printf("\nmatcher.group(2) value:%s", matcher.group(2));
       System.out.printf("\nmatcher.group(3) value:%s", matcher.group(3));

       // Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 4
       //System.out.printf("\nmatcher.group(4) value:%s", matcher.group(4));

   }
}

结果显示

matcher.group(0) value:2017-04-25
matcher.group(1) value:04-25
matcher.group(2) value:04
matcher.group(3) value:25
Process finished with exit code 0

预搜索(零宽断言)

注意:是对位置的匹配

(?=exp) 断言自身出现的位置的后面能匹配表达式exp

(?<=exp)断言自身出现的位置的前面能匹配表达式exp

(?!exp)断言此位置的后面不能匹配表达式exp

(?<!exp)断言此位置的前面不能匹配表达式exp

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BloDSbJW-1620374168384)(C:\Users\xiaoyoupei\AppData\Roaming\Typora\typora-user-images\image-20210507111702296.png)]

练习

正则的demo

public class test02 {
    public static void main(String[] args) {
        //在这个字符串:afwkeqf123123,测试是否符合\w+

        //表达式对象
        Pattern pattern = Pattern.compile("\\w+");

        //创建Matcher对象
        Matcher matcher = pattern.matcher("afwkeqf&&123123");

        //boolean flag1 = matcher.matches(); //匹配整个字符序列

        //boolean flag2 = matcher.find(); //扫描输入序列,查找与该模式匹配的子序列(一个个查)

//        System.out.println(matcher.find()); //true
//        System.out.println(matcher.find()); //true
//        System.out.println(matcher.find()); //false
//        System.out.println(matcher.find()); //false

//        System.out.println(matcher.find());
//        System.out.println(matcher.group()); //afwkeqf
//        System.out.println(matcher.find());
//        System.out.println(matcher.group()); //123123

//        while (matcher.find()) {
//            System.out.println(matcher.group()); //循环打印符合=的子序列
//        }
        String str = "a1234123b132412c124";
        String[] arrs = str.split("\\d+"); //用正则按数字进行切分
        System.out.println(Arrays.toString(arrs));


    }
}

正则运用于爬虫

/**
 * 网络爬虫取链接
 */
public class WebSpiderTest {

    public static String getURLContent(String urlStr, String charset) {
        StringBuilder sb = new StringBuilder();
        try {
            URL url = new URL(urlStr);
            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), Charset.forName(charset)));
            String temp = "";
            while ((temp = reader.readLine()) != null) {
                sb.append(temp);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public static List<String> getMatherSubstrs(String destStr, String regexStr) {
        Pattern pattern = Pattern.compile(regexStr); //取到超链接的地址
        Matcher matcher = pattern.matcher(destStr);
        List<String> result = new ArrayList<String>();
        while (matcher.find()) {
            //System.out.println(matcher.group(1));
            result.add(matcher.group(1));
        }
        return result;
    }

    public static void main(String[] args) {
        String destStr = getURLContent("http://www.made-in-china.com/", "UTF-8");

//      Pattern pattern = Pattern.compile("<a[\\s\\S]+?</a>"); //取到整个链接的内容

        List<String> result = getMatherSubstrs(destStr, "href=\"//(.+?)\"");
        for (String s : result) {
            System.out.println(s);
        }

    }
}
//      Pattern pattern = Pattern.compile("<a[\\s\\S]+?</a>"); //取到整个链接的内容

        List<String> result = getMatherSubstrs(destStr, "href=\"//(.+?)\"");
        for (String s : result) {
            System.out.println(s);
        }

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

友培

数据皆开源!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值