【问题标题】:Remove multiple instances with a regex expression, but not the text in between instances [duplicate]使用正则表达式删除多个实例,但不删除实例之间的文本[重复]
【发布时间】:2021-11-01 02:22:30
【问题描述】:

在使用bookdown 的长段落中,我插入了许多图像。将这些段落组合成一个字符串(在数据框中)后,我想删除与插入图像相关的降价文本,但不删除这些插入图像之间的任何文本。这是一个玩具示例。

text.string <- "writing ![Stairway scene](/media/ClothesFairLady.jpg) writing to keep ![Second scene](/media/attire.jpg) more writing"

str_remove_all(string = text.string, pattern = "!\\[.+\\)")
[1] "writing  more writing"

正则表达式不会在第一个右括号处停止,它会一直持续到最后一个并删除中间的“写入保留”。

我尝试申请String manipulation in R: remove specific pattern in multiple places without removing text in between instances of the pattern,它使用gsubfngsub,但无法让解决方案发挥作用。

请指出正确的方向来解决正则表达式删除指定字符串的问题,而不是字符串之间的字符。我更喜欢stringr 解决方案,但无论如何都可以。谢谢

【问题讨论】:

  • 另一个选项是str_replace_all(text.string, "!.*?\\)", ""),因为你真的只需要寻找你不想要的东西,因为这似乎遵循一个可靠的模式。就像您的示例一样,这确实会在子字符串之间留下双空格;这将使它成为一个空格:str_replace_all(text.string, "!.*?\\) ", "")

标签: r regex gsub stringr gsubfn


【解决方案1】:

我认为您也可以使用以下解决方案:

gsub("!\\[[^][]*\\]\\([^()]*\\)", "", text.string)

[1] "writing  writing to keep  more writing"

【讨论】:

    【解决方案2】:

    你必须使用下面的正则表达式

    "!\\[[^\\)]+\\)"
    

    或者你也可以使用这个:

    "!\\[.*?\\)"
    

    两种解决方案都提供 惰性 匹配而不是 贪婪 匹配,这是您问题的关键

    【讨论】:

    • 如果我正确阅读了区别,关于在第一种情况下如何使用字符类使评估变得懒惰的话,这将是一个有用的扩展,而不是在第二种情况下*?
    • 完美运行。懒惰在第一个实例中停止,而贪婪则不断地狼吞虎咽。这 。*?因此可以理解为“删除所有字符,直到到达 a 或第一个 )”?
    • @lawyeR 是的,.*?将从左到右不断添加字符到它的匹配,直到它找到一个“)”。之后它将再次寻找下一个“![”并重复该过程。懒惰的比赛可能很昂贵,因此我也给出了第一个选项(否定类)。否定类解决方案只是匹配所有不是“)”的字符,并保留从“)”到下一个“![”的所有内容,如果您有大量数据,它会成为更有效的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    相关资源
    最近更新 更多