【问题标题】:Removing html tags from a string in R从R中的字符串中删除html标签
【发布时间】:2021-02-05 13:36:36
【问题描述】:

我正在尝试将网页源代码读入 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"

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

【问题讨论】:

  • 修改了输入代码时出现的一些错误。
  • 这里发生了很多事情......首先,这是 R,所以没有 ;。您基本上是在寻找gsub 和适当的正则表达式(在这种情况下,已在此处回答:stackoverflow.com/questions/10225690/…)。代码还有其他问题(dim(tagLoc)[1] 没有做你认为的那样),但我认为这不是你问题的重点

标签: string r


【解决方案1】:

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

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

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

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

【讨论】:

  • 基本上它的作用是找到模式"&lt;.*?&gt;" in the htmlString'的任何实例,并将其替换为空字符串"",并返回结果。对于模式匹配,您应该学习正则表达式。唯一有点棘手的部分是".*?"? 使它不贪婪,所以如果你有多个标签,例如“ junk ”,它将匹配“”和“ a>" 而不是整个字符串。
  • "每次你尝试用正则表达式解析 HTML 时,邪恶的孩子都会流着处女的血,俄罗斯黑客会盗取你的 webapp" 来自this seminal answer。跨度>
  • 好吧,我会咬 - 删除!=解析
【解决方案2】:

您也可以使用 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"

Note that you should not use regexes to parse HTML.

【讨论】:

  • 请注意,输入字符串必须包含一些html标签,否则read_html会将参数视为本地文件路径
  • html_text(read_html(charToRaw(s))) 应该可以解决这个问题。
  • 我不能足够强调@Motin 的 cmets 和 patr1ckm 的回答。这么奇怪的错误。
【解决方案3】:

另一种方法,使用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"

【讨论】:

  • 注意:这个库需要Java,这可能是各种R服务器环境的限制
【解决方案4】:

使用 qdap 包的方法:

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

## > bracketX(test, "angle")
## [1] "junk junk junk junk"

【讨论】:

  • 我已经安装了您的软件包并查看了各种功能的源代码。 bracketX 对于更一般的问题非常有用。另一个用于工具箱。
【解决方案5】:

最好不要使用正则表达式解析html。 RegEx match open tags except XHTML self-contained tags

使用像XML 这样的包。使用例如htmlParse 在解析中获取 html 代码并使用 xpaths 查找与您相关的数量。

更新:

回答OP的问题

require(XML)
xData <- htmlParse('yourfile.html')
xpathSApply(xData, 'appropriate xpath', xmlValue)

【讨论】:

  • 这适用于这种情况吗?他根本不想解析标签,他想把它们去掉。
  • OP 可能只想使用xpathSapply(doc, 'somepath', xmlValue)
  • 当有人建议 HTML 正则表达式时,您提供的链接经常被提供,但这实际上只是一个指导方针而不是规则。我同意如果可能的话应该使用 XML(等),但有时它是不可能的或不切实际的。仅仅认为HTML + regex = bad 就是在回避决策。有时正则表达式是合适的。我们不知道数据格式或来源。这被投票了 2 次,但实际上并没有给 OP 一个答案。
  • OP 几乎没有详细说明他们最终想要什么。他们提供了一个简短的草图,将正则表达式的外观用作解析器。不通知 OP 这通常是一个坏主意是错误的。
【解决方案6】:

使用 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"

【讨论】:

  • 此代码的一个问题可能是,它将&lt; 的第一次出现替换为&gt; 的最后一次出现。所以当有多个html标签时,这可能是一个问题
【解决方案7】:

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

其次,您正在使用正则表达式来解析 HTML。 (它们没有出现在您的代码中,但它们在 str_locate_allstr_replace_all 的幕后使用。)这是另一个经典错误;请参阅here 了解更多说明。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-20
    • 2013-02-24
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多