R 中带有 gsub 和 grepl 的正则表达式:找到“,”后没有 space

Regex with gsub and grepl in R: finding ',' not followed by a space

我想在向量中找到任何具有 ',' 且后跟 space.

的元素

我在不同的来源发现:

为什么这些不会产生预期的结果? 考虑到 /S 除了 space 和 ^\s 应该是相同的...

grepl(',[^\b]', c('a,', 'b, ', 'c,')) # output: FALSE  TRUE FALSE expected: TRUE FALSE TRUE
gsub(',[^\b]', 'here', c('a,', 'b, ', 'c,')) # output: "a,"    "bhere" "c,"   expected: "ahere"    "b" "chere"
gsub(',[^\s]', 'here', c('a,', 'b, ', 'c,')) # output: "a,"    "bhere" "c," expected: "ahere"    "b" "chere"
gsub(',[^\S]', 'here', c('a,', 'b, ', 'c,')) # output: "a,"    "bhere" "c,"   expected: "a,"    "bhere" "c,"
gsub(',(\S)', 'here', c('a,', 'b, ', 'c,')) # output: "a,"  "b, " "c," expected: "ahere"    "b" "chere"

这不是作业,这是一个最小的工作示例。

更新解决方案 如果你想更换匹配的部件,也可以使用这个:

  • 这里只有一个捕获组[^0-9]匹配一个非数字字符,(?!\s)不被认为是捕获组
  • 然后我们使用反向引用来保留我们的捕获组 \1 并用 here 粘贴它作为替换
gsub("([^0-9]),(?!\s)", "\1here", c('a,', 'b, ', 'c,'), perl = TRUE)

[1] "ahere" "b, "   "chere"

这可能有帮助:

  • . 匹配每个字符,然后我们在捕获组
  • 中用文字 , 跟进它
  • (?!...) 是否定前瞻,意思是后面没有 ... 所以我们用 \s 替换 ... 因为我们不喜欢我们的捕获组字符被跟随一个白人 space
  • gregexprregexpr returns 给出匹配发生的 idices 的开始或结束位置的索引列表
  • 然后我们使用regmatches提取匹配元素
vec <- c('a,', 'b, ', 'c,')
unlist(regmatches(vec, gregexpr("(.,)(?!\s)", vec, perl = TRUE)))
or
#Filter(length, regmatches(vec, gregexpr("(.,)(?!\s)", vec, perl = TRUE)))

[[1]]
[1] "a,"

[[2]]
[1] "c,"

或者这个:

regmatches(vec, regexpr("(.,)(?!\s)", vec, perl = TRUE))

[1] "a," "c,"

试试这个:

grepl(",(?!\s)", c('a,', 'b, ', 'c,'), perl = TRUE)
gsub(",(?!\s)", "here", c('a,', 'b, ', 'c,'), perl = TRUE)

为什么你的表达式失败了?

  • ,[^\b]:逗号和任何不同于反斜杠和b
  • 的字符
  • ,[^\s]:逗号和任何不同于反斜杠和s
  • 的字符
  • ,[^\S]:逗号和任何不同于反斜杠和S
  • 的字符
  • ,(\S): 一个逗号和任何不同于空格的字符。

当您省略 perl=TRUE 表达式时,R 函数中的表达式可能会表现得很奇怪。

使用

gsub(',(?! )', '', x, perl=TRUE)
grepl(',(?! )', c('a,', 'b, ', 'c,'), perl=TRUE)

没有 perl=TRUE(?! ) 这样的前瞻将无法工作。

解释

--------------------------------------------------------------------------------
  ,                        ','
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
                             ' '
--------------------------------------------------------------------------------
  )                        end of look-ahead