【问题标题】:Negative lookahead in R to match delimited chunks in a string that do not contain an specific characterR中的负前瞻以匹配字符串中不包含特定字符的分隔块
【发布时间】:2020-12-23 07:52:40
【问题描述】:

我正在尝试(从字符串中)提取两个不包含空格的 \r\n 表达式之间的所有字符块。为此,我使用了负前瞻运算符。

这是我的字符串:

my_string <- "\r\nContent: base64\r\n\r\nDBhHB\r\nDGlV\r\nPAAHJ\r\nAwQU\r\n"

这是我尝试过的:

pat <- "\\r\\n+(?! )\\r\\n.*"

out <- unlist(regmatches(my_string,
                         regexpr(pat, my_string, perl=TRUE)))

这是我在 R 中得到的:

> out
 [1] "\r\n\r\nDBhHB\r\n"

如您所见,它在第一场比赛中停止。

编辑

在这种情况下,我的预期输出将是字符串的最后部分。

> out
 [1] "DBhHB\r\nDGlV\r\nPAAHJ\r\nAwQU\r\n"

如果字符串中间的其他块中还有一两个空格,我希望能够检索多个部分。

my_string <- "\r\nNot This\r\n\r\KeepThis\r\nKeepThis\r\nNot This\r\nKeepThis\r\n"

非常感谢基于 R 方法的建议。

提前致谢。

【问题讨论】:

  • 为了可读性和测试,我强烈建议缩短您的示例以使其更具可读性和清晰性,同时也说明“如果其他部分中还有一个或两个空格,则检索多个部分”的复杂性字符串中间的块”。如果输入是my_string &lt;- "\r\nBad Has Spaces\r\n\r\nKeepThis\r\nKeepThisToo\r\nNot This\r\nChunk2a\r\nChunk2b",您的预期输出是什么?
  • 至于解决方案,当您想在匹配后检查某些内容时,使用前瞻。但是您希望匹配中没有空格,而不是匹配后没有空格。我建议尝试 `pat = "\\r\\n[^]+\\r\\n"。在这种情况下,匹配的贪婪本性应该会让你获得最大的匹配。
  • 感谢@Gregor Thomas。我已经编辑了文本。关于您的其他建议,它确实适用于第一个示例,但当其他块中有多个空白时则无效。我会努力工作,看看我得到了什么。再次感谢
  • 类似regex101.com/r/hlrbQJ/1?或者,(?m)^\S+(?:\R\S+)*$ (demo)?
  • @allanvc 多么烦人,PCRE 库没有使用PCRE_BSR_ANYCRLF 选项编译。我用基本 R 解决方案更新了答案。

标签: r regex regex-lookarounds regex-negation


【解决方案1】:

我建议使用

(?m)^\S+(?:\R\S+)*$

请参阅regex demo。详情:

  • (?m) - 开启多行模式
  • ^ - 这个锚点现在匹配所有行的起始位置
  • \S+ - 一个或多个非空白字符
  • (?:\R\S+)* - 换行序列的零次或多次重复,然后是一个或多个非空白字符
  • $ - 一行结束。

R demo:

library(stringr)
my_string <- "\r\nContent: base64\r\n\r\nDBhHB\r\nDGlV\r\nPAAHJ\r\nAwQU\r\n"
pat <- "(?m)^\\S+(?:\\R\\S+)*$"
unlist(str_extract_all(my_string, pat))
## => [1] "DBhHB\r\nDGlV\r\nPAAHJ\r\nAwQU"

my_string <- "\r\nNot This\r\n\r\nKeepThis\r\nKeepThis\r\nNot This\r\nKeepThis\r\n"
unlist(str_extract_all(my_string, pat))
## => [1] "KeepThis\r\nKeepThis" "KeepThis"

基础 R 用法

请注意,在基本 R 中,使用 PCRE 引擎,而$ 在多行模式下(当使用 (?m) 时)仅在 \n 之前匹配。由于您有 \r\n 行尾,因此您不能使用普通的 $ 来标记行尾。使用 \r 不是一个好主意 (\r$),因为您不想在输出中包含 \r您可以使用(*ANYCRLF) PCRE 动词告诉 PCRE 将 CRLF、CR 或 LF 视为行结束序列

unlist(regmatches(my_string, gregexpr("(*ANYCRLF)(?m)^\\S+(?:\\R\\S+)*$",my_string, perl=TRUE)))

注意(*ANYCRLF) PCRE 动词必须在正则表达式模式的开头。

this R demo online

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 2023-03-12
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2019-06-05
    • 2020-06-11
    相关资源
    最近更新 更多