【问题标题】:Regex with gsub and grepl in R: finding ',' not followed by a space在 R 中使用 gsub 和 grepl 的正则表达式:查找 ',' 后面没有空格
【发布时间】:2021-10-24 22:23:56
【问题描述】:

我想在向量上找到任何元素,其中包含 ',' 后面没有空格

我在不同的来源找到了:

  • \b 或 \s 代表空格
  • \S 是除了空白之外的一切
  • [^] 应该是除了
  • 之外的所有内容

为什么这些不会产生预期的结果?考虑到 /S 是除了空格之外的所有内容,而 ^\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"

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

【问题讨论】:

  • 你的预期输出是什么?
  • 编辑了代码部分以包含预期的输出。

标签: r regex gsub grepl


【解决方案1】:

更新的解决方案 如果您想更换匹配的零件,也可以使用它:

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

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

这可能会有所帮助:

  • . 匹配每个字符,然后我们在捕获组中用文字 , 跟踪它
  • (?!...) 是负前瞻意思,后面没有 ...,所以我们将 ... 替换为 \\s,因为我们不希望我们的捕获组字符后跟空格
  • gregexprregexpr 返回一个索引列表,给出匹配发生的 idice 的开始或结束位置
  • 然后我们使用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,"

【讨论】:

  • 也许您可以使用"(.*?,)" 代替"(.,)"。因此,您可以提取“abc”,而*? 是非贪婪匹配。尝试使用“abc,def”和“(.*,)”与“(.*?,)”。 :-)
  • 当我们只有1个字符时,使用(.,)(.*?,)真的有关系吗?因为这里. 只匹配一个字符,而.* 匹配所有字符。
  • 你是对的,但我总是试图概括一个解决方案。 ;-)
  • 当你使用 perl=TRUE 时,那么基本的 R 正则表达式没有用(就像我在我的例子中使用的那样)?或者问题应该是我在哪里可以找到 R 中正则表达式的正确指南?
  • @Sapiens 我不明白,如果我的解决方案适合你,请告诉我?
【解决方案2】:

为什么你的表达失败了?

  • ,[^\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

【讨论】:

  • 很好的解释:)
【解决方案3】:

试试这个:

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

【讨论】:

  • 你能解释一下吗?
  • 我认为我们还必须为不匹配的元素删除, ,但不确定操作是否有错误或必须应用。在这种情况下,我们需要一个条件语句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
相关资源
最近更新 更多