首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于Regex的流模式匹配

基于Regex的流模式匹配
EN

Stack Overflow用户
提问于 2016-01-14 16:34:05
回答 1查看 199关注 0票数 3

我想解析一个在Warc版本0.9中格式化的大型文本文件。这类文本的一个示例是这里。如果您查看它,您将发现整个文档由以下条目组成。

代码语言:javascript
复制
[Warc Headers]

[HTTP Headers]

[HTML Content]

我需要从每个条目中提取URL和HTML内容(请注意,示例文件由多个页面条目组成,每个条目的格式与上面的内容类似)。

我在Java中使用了以下正则表达式:

代码语言:javascript
复制
Pattern.compile("warc/0\\.9\\s\\d+\\sresponse\\s(\\S+)\\s.*\n\n.*\n\n(.*)\n\n", Pattern.DOTALL)

其中第1组和第2组分别代表URL和HTML内容。这个代码有两个问题:

  1. 找到匹配的东西很慢。
  2. 只与第一页匹配。

Java代码:

代码语言:javascript
复制
if(mStreamScanner.findWithinHorizon(PAGE_ENTRY, 0) == null){
    return null;
} else {
    MatchResult result = mStreamScanner.match();
    return new WarcPageEntry(result.group(1), result.group(2));
}

问题:

  • 为什么我的代码只解析第一个页面条目?
  • 是否有更快的方法以流的方式解析大文本?
EN

回答 1

Stack Overflow用户

发布于 2016-01-14 18:50:56

我不会用正则表达式来处理这些庞大的HTML字符串。不如依靠文档的结构来代替呢?

例如:

代码语言:javascript
复制
HashMap<String, String> output = new HashMap<>();
Pattern pattern = Pattern.compile("^warc\\/0\\.9\\s\\d+\\sresponse\\s(\\S+)\\s.*");

try (InputStreamReader is = new InputStreamReader(new FileInputStream("excerpt.txt"), "UTF-8")) {               
    try (BufferedReader br = new BufferedReader(is)) {      
        String line;        
        while ((line = br.readLine()) != null) {
            Matcher matcher = pattern.matcher(line);

            if (matcher.matches()) {
                entityLoop: while (true) {
                    String url = matcher.group(1);

                    // skip header
                    int countEmptyLines = 0;
                    while ((line = br.readLine()) != null) {
                        if ("".equals(line)) {
                            countEmptyLines++;
                            if (countEmptyLines == 2) break;
                        }
                    }

                    // extract HTML
                    StringBuilder sb = new StringBuilder();
                    while ((line = br.readLine()) != null) {
                        matcher = pattern.matcher(line);
                        if (matcher.matches()) { 
                            // got all HTML; store our findings
                            output.put(url, sb.toString());
                            continue entityLoop; 
                        }
                        sb.append(line);
                    }
                    break; // no more url/html-entities available
                }
            }
        }
    }       
} catch (IOException e) {
    // do something smart
}

// now all your extracted data is stored in "output"

在上述代码中仍有改进的余地。但它应该给你一个如何开始的想法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34794835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档