使用多个正则表达式扫描文件

3

我有一些代码,它接收一个URL,读取文件并搜索与给定正则表达式匹配的字符串,并将任何匹配项添加到一个arrayList中,直到达到文件结尾。如何修改我的代码,以便在读取文件时,可以在同一次遍历中检查其他匹配其他正则表达式的字符串,而不必多次读取文件以检查每个不同的正则表达式?

    //Pattern currently being checked for
    Pattern name = Pattern.compile("<a id=.dg__ct(.+?)_hpl1.>(.+?)</a>");

    //Pattern I want to check for as well, currently not implemented
    Pattern date = Pattern.compile("[0-9]{2}/[0-9]{2}/[0-9]{4}");

    Matcher m;
    InputStream inputStream = null;
    arrayList = new ArrayList<String>();
    try {
        URL url = new URL(
                "URL to be read");
        inputStream = (InputStream) url.getContent();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        InputStreamReader isr = new InputStreamReader(inputStream);
        BufferedReader buf = new BufferedReader(isr);
        String str = null;
        String s = null;

        try {
            while ((str = buf.readLine()) != null) {

                m = name.matcher(str);
                while(m.find()){
                    s = m.group();
                    arrayList.add(s);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
4个回答

6

从第2个匹配器开始,您应该使用一个列表。而且不应该在finally块中执行此操作,因为如果其中一个流失败,则会进入该块。相反,应该使用finally块来关闭资源。

    List <Pattern> patterns = new ArrayList <Pattern> ();
    //Pattern currently being checked for
    patterns.add (Pattern.compile ("<a id=.dg__ct(.+?)_hpl1.>(.+?)</a>"));
    //Pattern I want to check for as well, currently not implemented
    patterns.add (Pattern.compile ("[0-9]{2}/[0-9]{2}/[0-9]{4}"));
    BufferedReader buf = null;
    List <String> matches = new ArrayList <String> ();
    try {
        URL url = new URL ("URL to be read");
        InputStream inputStream = (InputStream) url.getContent ();
        InputStreamReader isr = new InputStreamReader (inputStream);
        buf = new BufferedReader (isr);
        String str = null;
        while ((str = buf.readLine ()) != null) 
        {
            for (Pattern p : patterns) 
            {
                Matcher m = p.matcher (str);
                while (m.find ()) 
                    matches.add (m.group ());
            }
        }       
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
    finally  
    {
        if (buf != null) 
            try { buf.close (); } catch (IOException ignored) { /*empty*/}
    }

代码中未进行更正:应枚举特定的异常,而不是使用“Exception”。同时,Matcher仅在最内层循环中使用,因此应该在那里声明它,而不是在更大的范围内。小范围使得可以更容易地理解变量的使用。

我不确定util.Scanner.class是否可用于使从Url读取更加容易。请查看文档。


非常干净简洁的解决方案。谢谢。 - oipsl

2

不要使用正则表达式,而是使用一个能够正确解析HTML的Java库。

例如,请查看以下问题的答案:Java HTML Parsing


1
  1. 创建两个 Matcher 对象

    //正在检查的模式
    Matcher nameMatcher = Pattern.compile("<a id=.dg__ct(.+?)_hpl1.>(.+?)</a>").matcher();
    
    //我想要检查的模式,目前未实现
    Matcher dateMatcher = Pattern.compile("[0-9]{2}/[0-9]{2}/[0-9]{4}").matcher();
    
    
    // 其他内容...
    
  2. 将读取的字符串与每个匹配器进行比较

    while ((str = buf.readLine()) != null) {
    
            nameMatcher.reset(str);
    
            while(nameMatcher.find()){
                s = nameMatcher.group();
                arrayList.add(s);
            }
    
            dateMatcher.reset(str);
    
            while(nameMatcher.find()){
                s = nameMatcher.group();
                arrayList.add(s);
            }
        }
    

重要提示

使用reset(Charsequence)代替每次分配新的Matcher对象。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接