regex 如何在R中使用正则表达式在两个字符之间添加空格?

e5nqia27  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(142)

我想在两个标点符号(+和-)之间添加一个空格。我有以下代码:

s <- "-+"
str_replace(s, "([:punct:])([:punct:])", "\\1\\s\\2")

它坏了。能帮我一下吗?

eblbsuwk

eblbsuwk1#

这里有几个问题:

  • ICU正则表达式风格中的[:punct:]模式不匹配数学符号(\p{S}),它只匹配标点符号本身(\p{P}),如果您仍然希望匹配所有这些符号,请合并这两个类[\p{P}\p{S}]
  • "\\1\\s\\2"替换包含一个\s正则表达式转义序列,并且这些在替换模式中不受支持,您需要使用文本空格
  • str_replace仅替换第一个匹配项,请使用str_replace_all处理所有匹配项
  • 即使你使用了上面所有的建议,它仍然不能用于像-+?/这样的字符串,你需要使正则表达式的第二部分成为一个 * zero-width assertion *,一个正的前瞻,以便不消耗第二个标点符号。

因此,您可以使用

library(stringr)
s <- "-+?="
str_replace_all(s, "([\\p{P}\\p{S}])(?=[\\p{P}\\p{S}])", "\\1 ")
str_replace_all(s, "(?<=[\\p{P}\\p{S}])(?=[\\p{P}\\p{S}])", " ")
gsub("(?<=[[:punct:]])(?=[[:punct:]])", " ", s, perl=TRUE)

参见R demo online,所有三条线路均产生[1] "- + ? ="输出。
请注意,在PCRE regex风格(与gsubper=TRUE一起使用)中,POSIX字符类必须放在括号表达式中,因此在[[:punct:]]中使用了双括号。
此外,(?<=[[:punct:]])是一个正向后查找,它检查其模式是否立即出现在左侧,并且由于它是非消耗的,因此在替换中不需要任何向后引用。

相关问题