如何使用 R 的正则表达式用大括号替换方括号?
How to replace square brackets with curly brackets using R's regex?
由于 pandoc-citeproc 和 latex 之间的转换,我想替换这个
[@Fotheringham1981]
有了这个
\cite{Fotheringham1981}
.
下面的可重现示例说明了分别处理每个括号的问题。
x <- c("[@Fotheringham1981]", "df[1,2]")
x1 <- gsub("\[@", "\\cite{", x)
x2 <- gsub("\]", "\}", x1)
x2[1] # good
## [1] "\cite{Fotheringham1981}"
x2[2] # bad
## [1] "df[1,2}"
针对 C# 发现了类似的问题 solved,但没有使用 R 的 perly regex - 有什么想法吗?
编辑:
它应该能够处理长文档,例如
old_rmd <- "$p = \alpha e^{\beta d}$ [@Wilson1971] and $p = \alpha d^{\beta}$
[@Fotheringham1981]."
new_rmd1 <- gsub("\[@([^\]]*)\]", "\\cite{\1}", old_rmd, perl = T)
new_rmd2 <- gsub("\[@([^]]*)]", "\\cite{\1}", old_rmd)
new_rmd1
## "$p = \alpha e^{\beta d}$ \cite{Wilson1971} and $p = \alpha d^{\beta}$\n \cite{Fotheringham1981}."
new_rmd2
## [1] "$p = \alpha e^{\beta d}$ \cite{Wilson1971} and $p = \alpha d^{\beta}$\n\cite{Fotheringham1981}."
您需要使用捕获组。
x <- c("[@Fotheringham1981]", "df[1,2]")
gsub("\[@([^\]]*)\]", "\\cite{\1}", x, perl=T)
# [1] "\cite{Fotheringham1981}" "df[1,2]"
或
gsub("\[@(.*?)\]", "\\cite{\1}", x)
# [1] "\cite{Fotheringham1981}" "df[1,2]"
你可以使用
gsub("\[@([^]]*)]", "\\cite{\1}", x)
正则表达式细分:
\[@
- 文字 [@
符号序列
([^]]*)
- 匹配 0 次或多次出现的任何符号但 ]
的捕获组 1(请注意,如果 ]
出现在字符的开头 class, 不需要转义)
]
- 文字 ]
符号
您不需要对这个使用 perl=T
,因为字符 class 中的 ]
不会被转义。否则,将需要使用该选项。
另外,我认为我们应该只逃避必须逃避的。如果有办法避免 backslash hell,我们应该这样做。因此,您甚至可以使用
gsub("[[]@([^]]*)]", "\\cite{\1}", x)
这里是another demo
为什么基于 TRE 的正则表达式比 PCRE 的效果更好:
在 R 2.10.0 及更高版本中,默认的正则表达式引擎是 Ville Laurikari 的 TRE 引擎 [source]. The library's author states that time spent for matching grows linearly with increasing of input text length, while memory requirements are almost constant (tens of kilobytes). TRE is also said 的修改版本,以使用可预测和适度的内存消耗和二次最坏情况时间的长度使用正则表达式匹配算法。这就是为什么在处理较大的文档时最好依赖 TRE 而不是 PCRE 正则表达式。
这里匹配[@
然后设置一个捕获组,即所有在(...)内的,然后.*?
匹配最短的字符串直到]
:
gsub("\[(@.*?)\]", "\\cite{\1}", x)
## [1] "\cite{@Fotheringham1981}" "df[1,2]"
这是正则表达式的铁路图:
\[(@.*?)\]
由于 pandoc-citeproc 和 latex 之间的转换,我想替换这个
[@Fotheringham1981]
有了这个
\cite{Fotheringham1981}
.
下面的可重现示例说明了分别处理每个括号的问题。
x <- c("[@Fotheringham1981]", "df[1,2]")
x1 <- gsub("\[@", "\\cite{", x)
x2 <- gsub("\]", "\}", x1)
x2[1] # good
## [1] "\cite{Fotheringham1981}"
x2[2] # bad
## [1] "df[1,2}"
针对 C# 发现了类似的问题 solved,但没有使用 R 的 perly regex - 有什么想法吗?
编辑:
它应该能够处理长文档,例如
old_rmd <- "$p = \alpha e^{\beta d}$ [@Wilson1971] and $p = \alpha d^{\beta}$
[@Fotheringham1981]."
new_rmd1 <- gsub("\[@([^\]]*)\]", "\\cite{\1}", old_rmd, perl = T)
new_rmd2 <- gsub("\[@([^]]*)]", "\\cite{\1}", old_rmd)
new_rmd1
## "$p = \alpha e^{\beta d}$ \cite{Wilson1971} and $p = \alpha d^{\beta}$\n \cite{Fotheringham1981}."
new_rmd2
## [1] "$p = \alpha e^{\beta d}$ \cite{Wilson1971} and $p = \alpha d^{\beta}$\n\cite{Fotheringham1981}."
您需要使用捕获组。
x <- c("[@Fotheringham1981]", "df[1,2]")
gsub("\[@([^\]]*)\]", "\\cite{\1}", x, perl=T)
# [1] "\cite{Fotheringham1981}" "df[1,2]"
或
gsub("\[@(.*?)\]", "\\cite{\1}", x)
# [1] "\cite{Fotheringham1981}" "df[1,2]"
你可以使用
gsub("\[@([^]]*)]", "\\cite{\1}", x)
正则表达式细分:
\[@
- 文字[@
符号序列([^]]*)
- 匹配 0 次或多次出现的任何符号但]
的捕获组 1(请注意,如果]
出现在字符的开头 class, 不需要转义)]
- 文字]
符号
您不需要对这个使用 perl=T
,因为字符 class 中的 ]
不会被转义。否则,将需要使用该选项。
另外,我认为我们应该只逃避必须逃避的。如果有办法避免 backslash hell,我们应该这样做。因此,您甚至可以使用
gsub("[[]@([^]]*)]", "\\cite{\1}", x)
这里是another demo
为什么基于 TRE 的正则表达式比 PCRE 的效果更好:
在 R 2.10.0 及更高版本中,默认的正则表达式引擎是 Ville Laurikari 的 TRE 引擎 [source]. The library's author states that time spent for matching grows linearly with increasing of input text length, while memory requirements are almost constant (tens of kilobytes). TRE is also said 的修改版本,以使用可预测和适度的内存消耗和二次最坏情况时间的长度使用正则表达式匹配算法。这就是为什么在处理较大的文档时最好依赖 TRE 而不是 PCRE 正则表达式。
这里匹配[@
然后设置一个捕获组,即所有在(...)内的,然后.*?
匹配最短的字符串直到]
:
gsub("\[(@.*?)\]", "\\cite{\1}", x)
## [1] "\cite{@Fotheringham1981}" "df[1,2]"
这是正则表达式的铁路图:
\[(@.*?)\]