gsub的反函数

6

我有一些HTML代码需要处理。我想要提取特定的字符串。

我想要从字符串x中使用基本R来提取以下内容:coleman_l, SMOG4

这是我的代码:

x <- "<code>(hi)<a href=\"Read\">auto</a></code>(coleman_l, SMOG4)<br />Read</li>" 
#remove the string (this works)
gsub("a></code>(.+?)<br", "a></code><br", x)

#> gsub("a></code>(.+?)<br", "a></code><br", x)
#[1] "<code>(hi)<a href=\"Read\">auto</a></code><br />Read</li>"

#attempt to extract that information (doesn't work)
re <- "(?<=a></code>().*?(?=)<br)"
regmatches(x, gregexpr(re, x, perl=TRUE))

错误信息:
> regmatches(x, gregexpr(re, x, perl=TRUE)) 
Error in gregexpr(re, x, perl = TRUE) : 
  invalid regular expression '(?<=a></code>().*?(?=)<br)'
In addition: Warning message:
In gregexpr(re, x, perl = TRUE) : PCRE pattern compilation error
        'lookbehind assertion is not fixed length'
        at ')'

    enter code here

注意标记为正则表达式,但这是 R 特定的正则表达式。


1
stringr 中的 str_extract 函数是否有帮助? - Ben Bolker
@Ben 我修改了一下,现在建议使用基础R,这样以后搜索的人就能更方便地使用这个问题了。请将其添加为一个解决方案。 - Tyler Rinker
3
我知道你说要使用基础 R,但是使用 XML 库及其相关的 htmlTreeParsexmlTreeParse 比使用正则表达式处理 HTML 代码更合适。 - thelatemail
1
我还不是很清楚。像 gsub(".*a></code>(.+?)<br.*", "\\1", x) 这样的东西是你要找的吗? - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto 很好。请将其添加为解决方案。那是我尝试过的一种方法,但我的 gsub 尝试完全偏离了轨道。 - Tyler Rinker
3个回答

8
针对这类问题,我会使用反向引用来提取所需的部分。
x <- 
  "<code>(hi)<a href=\"Read\">auto</a></code>(coleman_l, SMOG4)<br />Read</li>" 
gsub(".*a></code>(.+?)<br.*", "\\1", x)
# [1] "(coleman_l, SMOG4)"

如果括号也需要被去除,请将它们添加到您正在匹配的"纯文本"部分中,但请记住它们需要被转义:

gsub(".*a></code>\\((.+?)\\)<br.*", "\\1", x)
# [1] "coleman_l, SMOG4"

7

顺便提一句,楼主最初的方法只需要稍加修改就可以实现。

> x
[1] "<code>(hi)<a href=\"Read\">auto</a></code>(coleman_l, SMOG4)<br />Read</li>"
> re <- "(?<=a></code>\\().*?(?=\\)<br)"
> regmatches(x, gregexpr(re, x, perl=TRUE))
[[1]]
[1] "coleman_l, SMOG4"

与其他建议的解决方案相比,这种方法的优点在于,如果存在多个匹配的可能性,则所有匹配都会显示出来。
> x <- '<code>(hi)<a href=\"Read\">auto</a></code>(coleman_l, SMOG4)<br />Read</li><code>(hi)<a href=\"Read\">auto</a></code>(coleman_l_2, SMOG4_2)<br />Read</li>'
> regmatches(x, gregexpr(re, x, perl=TRUE))
[[1]]
[1] "coleman_l, SMOG4"     "coleman_l_2, SMOG4_2"

1
дљ†дЄНиГље∞Ж"re"жЫіжФєдЄЇre <- "(?<=a></code>\\().*?(?=\\)<br)"пЉМйБњеЕНзђђдЇМдЄ™gsubеРЧпЉЯ - A5C1D2H2I1M1N2O1R2T1
我发誓我尝试过了,但是没用:P...正在修改我的解决方案。 - CHP

5

这将有效,尽管看起来很丑。

x<-"<code>(hi)<a href=\"Read\">auto</a></code>(coleman_l, SMOG4)<br />Read</li>"

x2 <- gsub("^.+(\\(.+\\)).+\\((.+)\\).+$","\\2",x)
x2
[1] "coleman_l, SMOG4"

正则表达式通常漂亮吗?+1 - A5C1D2H2I1M1N2O1R2T1
还没有看到有用且漂亮的正则表达式 :-) 感谢您的回复。+1 - Tyler Rinker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接