2026年02月05日/ 浏览 9
假设你正在分析一批新闻页面的原始HTML代码,目标是从中提取每篇文章的标题、关键词、元描述以及正文内容。虽然现代网络爬虫工具如rvest能直接解析DOM节点,但在某些情况下,比如只获得纯文本快照或处理自定义格式的日志时,正则表达式就成了不可或缺的利器。
首先,让我们构建一个模拟的文本片段:
r
raw_text <- ‘
‘
要从中提取标题,我们可以使用如下正则表达式:
r
title_pattern <- '<title>(.*?)</title>'
title_match <- regmatches(raw_text, regexec(title_pattern, raw_text))
title <- if (length(title_match[[1]]) > 1) title_match[[1]][2] else NA
这里的(.*?)是核心捕获组,?表示非贪婪匹配,确保只取第一个闭合标签前的内容。如果不加?,在多个<title>标签存在时可能误匹配到最后一个。
接下来提取关键词。观察content属性内的值,我们设计模式:
r
keyword_pattern <- 'name="keywords"\\s+content="(.*?)"'
keyword_match <- regmatches(raw_text, regexec(keyword_pattern, raw_text, ignore.case = TRUE))
keywords <- if (length(keyword_match[[1]]) > 1) unlist(strsplit(keyword_match[[1]][2], ",\\s*")) else NA
这里加入了ignore.case = TRUE以应对大小写变化,并用strsplit将逗号分隔的关键词拆分为向量,便于后续分析。
对于描述字段,逻辑类似:
r
desc_pattern <- 'name="description"\\s+content="(.*?)"'
desc_match <- regmatches(raw_text, regexec(desc_pattern, raw_text, ignore.case = TRUE))
description <- if (length(desc_match[[1]]) > 1) desc_match[[1]][2] else NA
最难处理的是正文。由于HTML结构复杂,简单正则容易出错。但我们可以通过定位特定类名的div标签来提高准确性:
r ‘
bodypattern <- '
body_match <- regmatches(raw_text, regexec(body_pattern, raw_text, dotall = TRUE))
body <- if (length(body_match[[1]]) > 1) body
if (!is.na(body)) {
body <- gsub(“<[^>]+>”, “”, body) # 移除所有HTML标签
body <- trimws(body) # 去除首尾空白
}
注意这里使用了dotall = TRUE参数(需加载stringr包或使用perl=TRUE),使得.可以匹配换行符,否则跨行内容会被截断。
整个提取过程可封装为函数:
r
extractarticle <- function(text) {
list(
title = extractbetween(text, ‘
‘))
)
}
extract_between <- function(x, start, end) {
s <- regexpr(paste0(start, “(.*?)”, end), x, perl = TRUE)
if (s == -1) return(NA)
substr(x, s + attr(s, “match.length”) – nchar(end),
s + attr(s, “capture.start”) – 2)
}
clean_html <- function(x) {
if (is.na(x)) return(x)
x <- gsub(“<[^>]+>”, “”, x)
trimws(x)
}