zoukankan      html  css  js  c++  java
  • Java中正则表达式、模式匹配与信息抽取

    正则表达式相关介绍详细参考:

    http://www.java3z.com/cwbwebhome/article/article8/Regex/Java.Regex.Tutorial.html


    引言

    记得几年前在做网页爬虫后的信息抽取时,针对网页源码中隐藏的要提取的信息,比如评论、用户信息等属性信息,直接利用HtmlParser得到。如此做倒是简单,不过利用的是网页的规范的tag标记。其实java中的正则表达式也可以用来实现这一功能。而且对于非tag的一些有规律的系列组合的字符串,正则表达式更能够发挥其卓越的功能。大学时候曾经就接触过正则表达式,不过只是略知皮毛。现在也无心学习,上面的链接网页有一个比较清晰的介绍可供参考。下面只是陈述一下自己在实验过程中利用正则表达式来进行模式匹配以抽取目标信息的尝试及一些简单发现。


    捕获组

    http://www.java3z.com/cwbwebhome/article/article8/Regex/Java.Regex.Tutorial.html#reg6

    模式中用()来表示捕获组,并且根据圆括号从左到右来编号。一个给定的正则表达式完整部分编号为0,然后()从左到右分别从1开始计数。我们可以得到任意捕获组的内容,下面用一个例子来展示:

    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		String stmt = "xx[new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39],";
    		String regex = "\[(.*?)\],";
    		Pattern p = Pattern.compile(regex);
    		Matcher m = p.matcher(stmt);
    		System.out.println(m.groupCount());
    		while(m.find()){
    			System.out.println(m.group(0));
    			System.out.println(m.group(1));
    		}
    	}


    输出结果为:

    1
    [new Date('08/24/2013'), 9.39],
    new Date('08/24/2013'), 9.39
    [new Date('08/24/2013'), 9.39],
    new Date('08/24/2013'), 9.39

    根据这,我们可以看到整个的表达式为捕获组0,可以匹配输出符合整个表达式模式的串。而()里面的捕获组则得到相应的匹配内容。

    量词

    同样上面的代码,当我们将正则表达式中的?去掉后,输出结果为:

    1
    [new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39],
    new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39

    则发现匹配的是全局部分,也就是所谓的贪婪策略。这就是由于贪婪、勉强和侵占量词的不同。详情可以参考:http://www.java3z.com/cwbwebhome/article/article8/Regex/Java.Regex.Tutorial.html#reg5_3

    因此,我个人认为如果用来信息抽取可能更多的用的是勉强量词。


    嵌套模式?

    假若我们抽取的模式里面包括很多频繁的子模式,是否能够用一个正则表达式来完成呢?比如针对上面的事例,如果将正则表达式修改为

    		String stmt = "xx[[new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39],];";
    		String regex = "\[(\[(.*?)\],)*\];";
    		Pattern p = Pattern.compile(regex);
    		Matcher m = p.matcher(stmt);
    		System.out.println(m.groupCount());
    		while(m.find()){
    			System.out.println(m.group());
    			System.out.println(m.group(0));
    			System.out.println(m.group(1));
    			System.out.println(m.group(2));
    		}

    目前还没有有效的办法获取最内层捕获组的匹配串,算是一个问题吧?虽然我们可以先用一个正则提取重复部分,然后再利用正则将其分解,一步不行吗?


    Tips

    1. .默认并不匹配所有的字符,例如换行空白的就不可以,这时候可以用Pattern p = Pattern.compile(regex,Pattern.DOTALL);来使其匹配所有

  • 相关阅读:
    java 实现前面带零的数字进行加减运算(保留前面的0)
    java 判断字符串是否是整数(纯数字:正整数、负整数、0)、至少包含一位小数、数字(可以是整数或小数)
    java 抽象类使用@Autowrited注入对象,子类直接使用父类的该属性
    java、springboot使用proguard混淆代码
    idea 使用阿里云仓库下载的jar包出现证书校验问题(PKIX:unable to find valid certification path to requested target)
    windows10安装zookeeper-3.6.2并生成zookeeper服务
    zookeeper-3.4.8 集群搭建
    zookeeper安装和使用 windows环境
    Dubbo入门---搭建一个最简单的Demo框架
    服务端高并发分布式架构演进之路
  • 原文地址:https://www.cnblogs.com/james1207/p/3339390.html
Copyright © 2011-2022 走看看