正则表达式替换 R 中字符串的部分/组

标签 r regex gsub capture-group

尝试对 bookdown 文档的 LaTeX(pdf_book 输出)进行后处理以折叠 biblatex 引用,以便能够使用 \usepackage[sortcites]{biblatex} 按时间顺序对它们进行排序稍后的。因此,我需要在 \\autocites 之后找到 }{ 并将其替换为 ,。我正在试验 gsub() 但找不到正确的咒语。

# example input
testcase <- "text \\autocites[cf.~][]{foxMapping2000}{wattPattern1947}{runkleGap1990} text {keep}{separate}"

# desired output
"text \\autocites[cf.~][]{foxMapping2000,wattPattern1947,runkleGap1990} text {keep}{separate}"

一个简单的方法是替换所有 }{

> gsub('\\}\\{', ',', testcase, perl=TRUE)
[1] "text \\autocites[cf.~][]{foxMapping2000,wattPattern1947,runkleGap1990} text {keep,separate}"

但这也会折叠 {keep}{separate}

然后我试图通过使用不同的组来替换以 \\autocites 开头的“单词”(没有空格的字符串)中的 }{ 并且失败了:

> gsub('(\\\\autocites)([^ \f\n\r\t\v}{}]+)((\\}\\{})+)', '\\1\\2\\3', testcase, perl=TRUE)
[1] "text \\autocites[cf.~][]{foxMapping2000}{wattPattern1947}{runkleGap1990} some text {keep}{separate}"

附录: 实际文档包含比上面的测试用例更多的行/元素。并非所有元素都包含 \\autocites,在极少数情况下,一个元素包含多个 \\autocites。我最初并不认为这是相关的。一个更真实的测试用例:

testcase2 <- c("some text",
"text \\autocites[cf.~][]{foxMapping2000}{wattPattern1947}{runkleGap1990} text {keep}{separate}",
"text \\autocites[cf.~][]{foxMapping2000}{wattPattern1947}{runkleGap1990} text {keep}{separate} \\autocites[cf.~][]{foxMapping2000}{wattPattern1947}")

最佳答案

单个 gsub 调用就足够了:

gsub("(?:\\G(?!^)|\\\\autocites)\\S*?\\K}{", ",", testcase, perl=TRUE)
## => [1] "text \\autocites[cf.~][]{foxMapping2000,wattPattern1947,runkleGap1990} text {keep}{separate}"

参见 regex demo .这里,(?:\G(?!^)|\\autocites) 匹配上一个匹配的末尾或 \autocites 字符串,然后它匹配任意 0 个或多个非空白字符,但尽可能少,然后 \K 丢弃当前匹配缓冲区中的文本并使用最终被逗号替换的 }{ 子字符串。

还有一个非常可读的解决方案,其中包含一个正则表达式和一个使用 stringr::str_replace_all 的固定文本替换:

library(stringr)
str_replace_all(testcase, "\\\\autocites\\S+", function(x) gsub("}{", ",", x, fixed=TRUE))
# => [1] "text \\autocites[cf.~][]{foxMapping2000,wattPattern1947,runkleGap1990} text {keep}{separate}"

这里,\\autocites\S+ 匹配 \autocites 然后是 1+ 个非空白字符,并且 gsub("}{", ",", x, fixed=TRUE) 将匹配文本中的每个 }{ 替换(非常快)为 ,

关于正则表达式替换 R 中字符串的部分/组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58543179/

相关文章:

regex - R gsub 单双引号

facebook - 获取 facebook 公共(public)页面评级和评论

r - 在 sparklyr 中断开连接后,spark 数据帧是否会自动删除?如果没有,我们该怎么做?

r - 安装Spark 1.4自带的SparkR

regex - 多 grep 到 1 grep?我应该改变它吗?我该怎么做?

gsub 中的 Ruby 正则表达式捕获组

html - 自制的 Shiny table

regex - 从字符串中提取可变长度的数字

c# - 正则表达式从给定字符串中提取日期时间

ruby-on-rails - 如何使用 gsub 删除 .在 ruby 字符串的末尾?