代码之家  ›  专栏  ›  技术社区  ›  geotheory

提取字符串中的第一个句子

  •  6
  • geotheory  · 技术社区  · 8 年前

    我想用regex从下面摘录第一句话。我想要实现的规则(我知道这不是通用的解决方案)是从字符串开始提取 ^ 最多(含) 以小写字母或数字开头的第一个句号/感叹号/问号 .

    require(stringr)
    
    x = "Bali bombings: U.S. President George W. Bush amongst many others has condemned the perpetrators of the Bali car bombing of October 11. The death toll has now risen to at least 187."
    

    到目前为止,我最好的猜测是尝试实现一个非贪婪的 string-before-match approach 在这种情况下失败:

    str_extract(x, '.+?(?=[a-z0-9][.?!] )')
    [1] NA
    

    非常感谢任何提示。

    2 回复  |  直到 8 年前
        1
  •  6
  •   Wiktor Stribiżew    8 年前

    你把 [a-z0-9][.?!] 如果您计划使用,则需要将其转换为非消耗性的前瞻模式 str_extract :

    > str_extract(x, '.*?[a-z0-9][.?!](?= )')
    [1] "Bali bombings: U.S. President George W. Bush amongst many others has condemned the perpetrators of the Bali car bombing of October 11."
    

    看见 this regex demo .

    细节

    • .*? -除换行符以外的任何0+字符
    • [a-z0-9] -ASCII小写字母或数字
    • [.?!] -a . , ? 或 !
    • (?= ) -后跟一个文本空格。

    或者,您可以使用 sub :

    sub("([a-z0-9][?!.])\\s.*", "\\1", x)
    

    看见 this regex demo .

    细节

    • ([a-z0-9][?!.]) -第1组(参考 \1 从替换模式):ASCII小写字母或数字,然后是 ? , ! 或 .
    • \s -空白
    • .* -任意0个以上字符,尽可能多(直到字符串末尾)。
        2
  •  3
  •   dmi3kno    8 年前

    corpus 在确定句子边界时,对缩写有特殊处理:

    library(corpus)       
    text_split(x, "sentences")
    #>   parent index text                                                                                                                           
    #> 1 1          1 Bali bombings: U.S. President George W. Bush amongst many others #> has condemned the perpetrators of the Bali car bombing of Oct…
    #> 2 1          2 The death toll has now risen to at least 187.  
    

    还有一个有用的数据集,包含包括英语在内的多种语言的常用缩写。看见 corpus::abbreviations_en ,可用于消除句子边界的歧义。