34

我正在尝试将网页源读入 R 并将其作为字符串处理。我正在尝试将段落取出并从段落文本中删除 html 标签。我遇到了以下问题:

我尝试实现一个函数来删除 html 标签:

cleanFun=function(fullStr)
{
 #find location of tags and citations
 tagLoc=cbind(str_locate_all(fullStr,"<")[[1]][,2],str_locate_all(fullStr,">")[[1]][,1]);

 #create storage for tag strings
 tagStrings=list()

 #extract and store tag strings
 for(i in 1:dim(tagLoc)[1])
 {
   tagStrings[i]=substr(fullStr,tagLoc[i,1],tagLoc[i,2]);
 }

 #remove tag strings from paragraph
 newStr=fullStr
 for(i in 1:length(tagStrings))
 {
   newStr=str_replace_all(newStr,tagStrings[[i]][1],"")
 }
 return(newStr)
};

这适用于某些标签,但不适用于所有标签,失败的示例是以下字符串:

test="junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk"

目标是获得:

cleanFun(test)="junk junk junk junk"

但是,这似乎不起作用。我认为这可能与字符串长度或转义字符有关,但我找不到涉及这些的解决方案。

4

7 回答 7

74

这可以通过正则表达式和 grep 系列简单地实现:

cleanFun <- function(htmlString) {
  return(gsub("<.*?>", "", htmlString))
}

这也适用于同一字符串中的多个 html 标签!

这会在 htmlString 中找到该模式的任何实例<.*?>并将其替换为空字符串“”。这 ?in.*?使其不贪心,因此如果您有多个标签(例如,<a> junk </a>),它将匹配<a></a>不是整个字符串。

于 2013-06-21T03:49:30.773 回答
26

您还可以使用rvest包中的两个函数来执行此操作:

library(rvest)

strip_html <- function(s) {
    html_text(read_html(s))
}

示例输出:

> strip_html("junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk")
[1] "junk junk junk junk"

请注意,您不应使用正则表达式来解析 HTML

于 2015-12-17T21:54:08.503 回答
10

另一种方法 using tm.plugin.webmining,它在XML内部使用。

> library(tm.plugin.webmining)
> extractHTMLStrip("junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk")
[1] "junk junk junk junk"
于 2013-06-21T14:54:43.987 回答
7

使用 qdap 包的方法:

library(qdap)
bracketX(test, "angle")

## > bracketX(test, "angle")
## [1] "junk junk junk junk"
于 2013-06-21T04:24:06.653 回答
4

最好不要使用正则表达式解析 html。RegEx 匹配打开的标签,XHTML 自包含标签除外

使用像XML. 使用例如解析它的 html 代码htmlParse并使用 xpaths 查找与您相关的数量。

更新:

回答OP的问题

require(XML)
xData <- htmlParse('yourfile.html')
xpathSApply(xData, 'appropriate xpath', xmlValue)
于 2013-06-21T05:46:01.707 回答
3

使用 sub 或 gsub 可能更容易?

> test  <- "junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk"
> gsub(pattern = "<.*>", replacement = "", x = test)
[1] "junk junk junk junk"
于 2013-06-21T04:31:32.293 回答
2

首先,您的主题行具有误导性;您发布的字符串中没有反斜杠。你已经成为经典错误之一的受害者:没有卷入亚洲的陆战那么糟糕,但同样值得注意。您误将 R 用于\将转义字符表示为文字反斜杠。在这种情况下,\"表示双引号,而不是两个文字字符\"。如果按字面处理转义字符,您可以使用它cat来查看字符串的实际外观。

其次,您正在使用正则表达式来解析 HTML。(它们不会出现在您的代码中,但它们会在str_locate_all和的内部使用str_replace_all。)这是另一个典型的错误;请参阅此处了解更多说明。

第三,您应该在帖子中提到您正在使用该stringr软件包,但相比之下,这只是一个小错误。

于 2013-06-21T03:48:39.517 回答