【问题标题】:Regex expression failing in R正则表达式在 R 中失败
【发布时间】:2021-10-10 03:18:36
【问题描述】:

我想出了以下正则表达式,以识别多个字符串的间隙,如果它前面有一个间隙和模式,并确认它在 regexr.com 中工作

模式是:

(?=\s{2,}.\s{2,})\s{2,}

但是当我在 grep() 中的 R 中使用它时,它似乎失败了?甚至包括转义字符符号:

exampleText = "1  Building  Apartment  City"
gsub("\\(?=\\s{2,}.\\s{2,}\\)\\s{2,}",",",exampleText)

希望得到如下输出:

"1 Building,Apartment,City"

并且正则表达式仅在字符串的任一侧有双倍空格或更大的空格时才匹配。

得到错误“无效的正则表达式”

【问题讨论】:

  • 如果我复制/粘贴该代码,我不会收到该错误 - 我只是得到一个空结果。是否取决于exampleText 的值?请确保您的示例 [reproducible ](stackoverflow.com/questions/5963269/…) 具有可用于测试的示例输入和所需输出。
  • 猜测您想从前瞻中删除转义并添加参数perl = TRUE - grep("(?=\\s{2,}.\\s{2,})\\s{2,}","replace text",exampleText, perl = TRUE)。
  • 感谢您的反馈,我已经用值更新了问题。希望有助于进一步解释
  • (?=...) 是 lookahead,应该遵循其他模式;你的意思是(?<=...) 用于lookbehind(以及添加perl=TRUE,正如建议的那样)?

标签: r regex


【解决方案1】:

R 的 PCRE 实现(用于前瞻/后瞻)不允许可变的重复量词(例如,{2,});来自?regex:

     Patterns '(?=...)' and '(?!...)' are zero-width positive and
     negative lookahead _assertions_: they match if an attempt to match
     the '...' forward from the current position would succeed (or
     not), but use up no characters in the string being processed.
     Patterns '(?<=...)' and '(?<!...)' are the lookbehind equivalents:
     they do not allow repetition quantifiers nor '\C' in '...'.

(最后一行)。例如,我们将看到:

gsub("(?<=\\s{2,})Quux", ",", exampleText, perl=TRUE)
# Warning in gsub("(?<=\\s{2,})Quux", ",", exampleText, perl = TRUE) :
#   PCRE pattern compilation error
#   'lookbehind assertion is not fixed length'
#   at '(?<=\s{2,})Quux'

但如果我们更改为"(?&lt;=\\s{2})",则不会出现此类错误。因此,您的环视表达式需要是固定宽度的。

一些建议,这两个都会产生预期的结果:

txt <- gsub("(?<=\\s{2})(\\S*)(?=\\s{2})", "\\1,", exampleText, perl=TRUE)
txt <- gsub("(?<=\\s\\s)(\\S*)(?=\\s\\s)", "\\1,", exampleText, perl=TRUE)
txt
# [1] "1  Building,  Apartment,  City"

如果需要,您可以使用更多模式修复多空间:

gsub("\\s+", " ", gsub(",  ", ",", txt))
# [1] "1 Building,Apartment,City"

由于看起来好像您正在创建以逗号分隔的文本,但大多数读者会选择性地丢弃周围的空格:

txt
# [1] "1  Building,  Apartment,  City"
str(read.csv(text = txt, header = FALSE, strip.white = TRUE))
# 'data.frame': 1 obs. of  3 variables:
#  $ V1: chr "1  Building"
#  $ V2: chr "Apartment"
#  $ V3: chr "City"

【讨论】:

    猜你喜欢
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    相关资源
    最近更新 更多