悠悠楠杉
如何利用R语言与正则表达式精准提取字符串中的关键信息
假设你正在分析一批新闻页面的原始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 <- '
清理HTML标签
if (!is.na(body)) {
body <- gsub("<[^>]+>", "", body) # 移除所有HTML标签
body <- trimws(body) # 去除首尾空白
}
注意这里使用了dotall = TRUE参数(需加载stringr包或使用perl=TRUE),使得.可以匹配换行符,否则跨行内容会被截断。
整个提取过程可封装为函数:
r
extractarticle <- function(text) {
list(
title = extractbetween(text, '
keywords = strsplit(extractbetween(text, 'name="keywords" content="', '"'), ",\s*")[[1]], description = extractbetween(text, 'name="description" content="', '"'),
body = cleanhtml(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)
}
