【问题标题】:Extract websites links from a text in R从R中的文本中提取网站链接
【发布时间】:2013-03-22 20:14:59
【问题描述】:

我有多个文本,每个文本都可能包含对一个或多个 Web 链接的引用。例如:

 text1= "s@1212a as www.abcd.com asasa11". 

如何提取:

   "www.abcd.com" 

从R中的这个文本?换句话说,我希望提取以www 开头并以.com 结尾的模式

【问题讨论】:

    标签: r


    【解决方案1】:

    regmatches 这种方法使用regexpr/grepgexprregmatches。我扩展了测试数据以包含更多示例。

    text1 <- c("s@1212a www.abcd.com www.cats.com", 
               "www.boo.com", 
               "asdf",
               "blargwww.test.comasdf")
    
    # Regular expressions take some practice.
    # check out ?regex or the wikipedia page on regular expressions
    # for more info on creating them yourself.
    pattern <- "www\\..*?\\.com"
    # Get information about where the pattern matches text1
    m <- gregexpr(pattern, text1)
    # Extract the matches from text1
    regmatches(text1, m)
    

    这给了

    > regmatches(text1, m) ##
    [[1]]
    [1] "www.abcd.com" "www.cats.com"
    
    [[2]]
    [1] "www.boo.com"
    
    [[3]]
    character(0)
    
    [[4]]
    [1] "www.test.com"
    

    注意它返回一个列表。如果我们想要一个向量,您可以在结果上使用unlist。这是因为我们使用了gregexpr,这意味着我们的字符串中可能有多个匹配项。如果我们知道最多有一个匹配项,我们可以改用regexpr

    > m <- regexpr(pattern, text1)
    > regmatches(text1, m)
    [1] "www.abcd.com" "www.boo.com"  "www.test.com"
    

    但是请注意,这会将所有结果作为向量返回,并且仅从每个字符串返回一个结果(请注意 www.cats.com 不在结果中)。不过,总的来说,我认为这两种方法中的任何一种都比gsub 方法更可取,因为如果没有找到结果,这种方法将返回整个输入。例如看一下:

    > gsub(text1, pattern=".*(www\\..*?\\.com).*", replace="\\1")
    [1] "www.abcd.com" "www.boo.com"  "asdf"         "www.test.com"
    

    即使在将模式修改为更健壮一点之后也是如此。我们仍然在结果中得到“asdf”,即使它显然与模式不匹配。

    无耻愚蠢的自我推销:regmatches 是在 R 2.14 中引入的,所以如果你坚持使用早期版本的 R,你可能会不走运。除非你能够安装 future2.14 包 from my github repo,它为 2.14 中引入的功能提供了一些支持到早期版本的 R。

    strapplyc。与上面 ## 给出相同结果的另一种方法是:

    library(gsubfn)
    strapplyc(test1, pattern)
    

    正则表达式下面是一些关于如何破译正则表达式的解释:

    pattern <- "www\\..*?\\.com"
    

    解释:

    www 匹配 www 部分

    \\. 我们需要使用\\ 转义一个实际的“点”字符,因为普通的. 表示正则表达式中的“任何字符”。

    .*? . 代表任何字符,* 告诉匹配 0 次或多次,? 跟在 * 之后告诉它不要贪心。否则,“asdf www.cats.com www.dogs.com asdf”会将所有“www.cats.com www.dogs.com”作为一个匹配项进行匹配,而不是识别出其中有两个匹配项。

    \\. 再次我们需要转义一个实际的点字符

    com这部分匹配我们要匹配的结尾'com'

    总而言之,它说:从 www 开始。然后匹配任何字符,直到到达第一个“.com”

    【讨论】:

    • 另请注意,它确实从 blargwww.test.comasdf 中提取了 www.test.com,这可能是可取的,也可能不是可取的,但在没有关于这种情况的输入的情况下,我决定允许它。
    • @G.Grothendieck 这也是一个不错的方法 - 为什么不将其添加为答案?
    • 我已将其添加到您的答案中。
    • 我添加了一些关于正则表达式的解释——希望这能让正则表达式新手更容易理解答案......
    【解决方案2】:

    查看 gsub 函数:

    x = "s@1212a as www.abcd.com asasa11"
    gsub(x=x, pattern=".*(www.*com).*", replace="\\1")
    

    基本思路是将要保留的 txt 括在括号中,然后用它替换整行。 gsub "\\1" 的替换参数指的是括号中的内容。

    【讨论】:

    • 我觉得这个不好。例如,这将提取像 wwwabcdcom 这样的词,并且只会提取。
    • gsub(x=x, pattern=".*(www\\..*\\.com).*", "\\1") 将确保点在 www 之后和在 com 之前,但对于不熟悉正则表达式的人来说更难理解。
    • @Kith 如果你有 2 个网页链接,即使这个也不好。来吧,如果您认为 OP 不熟悉正则表达式,您应该更好地解释您所做的事情。例如\\1的含义需要更多解释。
    • 请注意,如果在字符串中未找到该模式,则此方法将返回整个输入 - 这可能是不可取的...
    【解决方案3】:

    这里的解决方案很棒而且很基础。对于那些想要快速解决方案的人,您可以使用qdapgenXtract。这个函数基本上需要一个左元素和一个右元素,它将提取两者之间的所有内容。通过设置with = TRUE,它将包含这些元素:

    text1 <- c("s@1212a www.abcd.com www.cats.com", 
        "www.boo.com", 
        "asdf",
        "http://www.talkstats.com/ and http://stackoverflow.com/",
        "blargwww.test.comasdf")
    
    library(qdap)
    genXtract(text1, "www.", ".com", with=TRUE)
    
    ## > genXtract(text1, "www.", ".com", with=TRUE)
    ## $`www.  :  .com1`
    ## [1] "www.abcd.com" "www.cats.com"
    ## 
    ## $`www.  :  .com2`
    ## [1] "www.boo.com"
    ## 
    ## $`www.  :  .com3`
    ## character(0)
    ## 
    ## $`www.  :  .com4`
    ## [1] "www.talkstats.com"
    ## 
    ## $`www.  :  .com5`
    ## [1] "www.test.com"
    

    PS 如果您查看该函数的代码,它是 Dason 解决方案的包装器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 2016-04-18
      • 2018-09-13
      • 2011-04-14
      • 1970-01-01
      • 2011-02-14
      • 2017-04-18
      相关资源
      最近更新 更多