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

    引言

    记得几年前在做网页爬虫后的信息抽取时,针对网页源码中隐藏的要提取的信息,比如评论、用户信息等属性信息,直接利用HtmlParser得到。如此做倒是简单,不过利用的是网页的规范的tag标记。其实java中的正则表达式也可以用来实现这一功能。而且对于非tag的一些有规律的系列组合的字符串,正则表达式更能够发挥其卓越的功能。大学时候曾经就接触过正则表达式,不过只是略知皮毛。现在也无心学习,上面的链接网页有一个比较清晰的介绍可供参考。下面只是陈述一下自己在实验过程中利用正则表达式来进行模式匹配以抽取目标信息的尝试及一些简单发现。
     
     
    捕获组
     
     
    模式中用()来表示捕获组,并且根据圆括号从左到右来编号。一个给定的正则表达式完整部分编号为0,然后()从左到右分别从1开始计数。我们可以得到任意捕获组的内容,下面用一个例子来展示:
     
    [java] 
    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));  
        }  
    }  
     
    输出结果为:
    [plain 
    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,可以匹配输出符合整个表达式模式的串。而()里面的捕获组则得到相应的匹配内容。
     
    量词
    同样上面的代码,当我们将正则表达式中的?去掉后,输出结果为:
    [plain] view plaincopy
    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
     
    因此,我个人认为如果用来信息抽取可能更多的用的是勉强量词。
     
     
    嵌套模式?
    假若我们抽取的模式里面包括很多频繁的子模式,是否能够用一个正则表达式来完成呢?比如针对上面的事例,如果将正则表达式修改为
    [java] 
    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);来使其匹配所有
  • 相关阅读:
    大数据量问题,按需按实际查询而不是一次加载。
    spring中注解事务认识
    sqlmap文件在tomcat7中运行报错原因及<![CDATA[ ]]>
    网站404,500错误页面的处理,及500异常写入errorLog日志
    javascript div z-index, input tabindex属性说明
    sqlmap映射继承机制及映射字段顺序与SQL查询字段顺序无关
    jquery类选择器无法取得对象问题原因
    linux服务器初步印象,远程连接mysql数据库,传输文件,启动/关闭tomcat命令
    Linux iptables 防火墙详解
    Nginx之location 匹配规则详解
  • 原文地址:https://www.cnblogs.com/gisblogs/p/3956131.html
Copyright © 2011-2022 走看看