我正在使用R中的LaTex文档,我需要将{#1 \over #2}
更改为\frac{#1}{#2}
。
使用简单的表达式:
{1\over 2}
{x^2+y^2\over \lambda}
我可以使用stringr::str_replace()
或gsub
基本函数和正则表达式\\{([\\^a-z0-9\\\\\\s\\+\\-\\*/\(\)]+)\\s*\\\\over\\s*([\\^a-z0-9\\\\\\s\\+\\-\\*/\(\)]+)\\}
(我想必须有更好的方法来执行此操作。我尝试使用{{1}但它捕获的比我想要的要多。)
但是当我使用像:
这样的表达式时\\{(.+)\\s*\\\\over\\s*(.*)\\}
{e^{2c} \over x-1}
或更复杂的表达:
{2yz\over 1+x^{2} }
是否有正则表达式可以捕获所有替代品?感谢
答案 0 :(得分:1)
给出一些示例字符串:
> strings
[1] "{1\\over 2}" "{x^2+y^2\\over \\lambda}"
这个怪物:
> unlist(
lapply(
strsplit(
sub("\\}$","",
sub("^\\{","",strings)),"\\\\over"),
function(x){paste0("\\frac{",x[1],"}{",x[2],"}")}))
产生
[1] "\\frac{1}{ 2}" "\\frac{x^2+y^2}{ \\lambda}"
如果源字符串中有多个\over
,则会中断。也许在许多其他情况下......哦,如果在第一个{
之前或结束}
之后有空格,它就不起作用。
在你的其他例子中,你得到了这个:
in out
[1,] "{1\\over 2}" "\\frac{1}{ 2}"
[2,] "{x^2+y^2\\over \\lambda}" "\\frac{x^2+y^2}{ \\lambda}"
[3,] "{e^{2c} \\over x-1}" "\\frac{e^{2c} }{ x-1}"
[4,] "{2yz\\over 1+x^{2} }" "\\frac{2yz}{ 1+x^{2} }"
答案 1 :(得分:0)
这可以帮助您完成示例:
library(stringr)
s <- "Expression 1 is {1\\over 2}.
Expression 2 is {x^2+y^2\\over \\lambda}, yes it is.
Expression 3 is {e^{2c} \\over x-1}.
The last expression: {2yz\\over 1+x^{2} }, all done now."
s2 <- str_replace_all(s,
"\\{(.*?)\\s{0,}\\\\over\\s{0,}(.*?)\\}",
"\\frac\\{\\1\\}\\{\\2\\}")
s2
[1] "Expression 1 is frac{1}{2}.\n\nExpression 2 is frac{x^2+y^2}{\\lambda}, yes it is.\n\nExpression 3 is frac{e^{2c}}{x-1}.\n\nThe last expression: frac{2yz}{1+x^{2} }, all done now."
唯一的问题是最后一个表达式中仍然存在空格,这可能不是问题,因为它存在于原始表达式中:
frac{2yz}{1+x^{2} }
答案 2 :(得分:0)
这种方法可以处理:
例如,请注意下面的示例中第一个出现{...}之前的第二个输入行上的{jjj},其中\ over按预期工作。
它使用可以处理平衡括号的gsubfn
。首先创建一个与我的答案here中的原型对象类似的原型对象p
。 p
将计数器k
初始化为0,并为每个{递增计数器{并为每个递减}。它替换了任何{其中k = 1!还有任何},其中k = 0!
然后将!...\over...!
替换为\frac{...}{...}
,并将剩余的!...!
替换为{...}
。
我们假设了!不会出现在输入中,但如果它确实选择了不同的字符。
library(gsubfn)
library(magrittr)
# test input
s <- c("abc {1\\over 2} def {x^2+y^2\\over \\lambda} ghi { 12 } XYZ",
"X {jjj} A {e^{2c} \\over x-1} jkl {2yz\\over 1+x^{2} } Z")
# processing
p <- proto(
pre = function(.) .$k <- 0,
fun = function(., x) {
if (x == "{") .$k <- .$k + 1 else if (x == "}") .$k <- .$k - 1
if (x == "{" && .$k == 1) "!" else if (x == "}" && .$k == 0) "!" else x
})
s %>%
gsubfn("[{}]", p, .) %>%
gsub("!([^!]*)\\\\over ([^!]*)!", "\\\\frac{\\1}{\\2}", .) %>%
gsub("!([^!]*)!", "{\\1}", .)
给出这个结果:
[1] "abc \\frac{1}{2} def \\frac{x^2+y^2}{\\lambda} ghi { 12 } XYZ"
[2] "X {jjj} A \\frac{e^{2c} }{x-1} jkl \\frac{2yz}{1+x^{2} } Z"
答案 3 :(得分:0)
x=c("{e^{2c} \\over x-1}","{2yz\\over 1+x^{2} },,dty{k^4e{-rpi/3}\\over\\sqrt{2pik}}")
gsub("\\{(.*?)\\\\over(.*?)\\}","\\\frac{\\1}{\\2}",x)
[1] "\frac{e^{2c} }{ x-1}"
[2] "\frac{2yz}{ 1+x^{2} },,dty\frac{k^4e{-rpi/3}}{\\sqrt{2pik}}"
说明:
\{(.*?)\\over(.*?)\\
第一捕获组(。*?)
\\
匹配
character \ literally(区分大小写)匹配字符
字面意思(区分大小写)
第二捕获组(。*?)
\\
匹配字符\字面(区分大小写)
答案 4 :(得分:0)
我很喜欢这个问题。
在某些时候你必须解析文档。来自parse_tex
的{{1}}考虑到LaTeX不是普通的TeX,但似乎在这里做得不错。对于TeXCheckR
的多行实例,虽然原理与我想的相同,但需要更改脚本。
挑战在于持续分数。
\over
测试TeX文档:
library(data.table) # for shift
library(TeXCheckR) # for parse_tex
locate_over <- function(doc_parsed) {
lead <- function(x, n) data.table::shift(x, n = n, type = "lead", fill = "")
char <- .subset2(doc_parsed, "char")
which(char == "\\" &
lead(char == "o", 1L) &
lead(char == "v", 2L) &
lead(char == "e", 3L) &
lead(char == "r", 4L))
}
over2frac <- function(lines, verbose = FALSE) {
out <- lines
for (i in seq_along(lines)) {
if (grepl("\\over", lines[i], fixed = TRUE)) {
i_parsed <- parse_tex(lines[i])
# Find lhs
for (j in locate_over(i_parsed)) {
lhs_start <- max(which(.subset2(i_parsed, "char") %chin% c("$", "{") &
.subset2(i_parsed, "column") < j &
.subset2(i_parsed, "tex_group") == .subset2(i_parsed[j], "tex_group")))
rhs_end <- min(which(.subset2(i_parsed, "char") %chin% c("$", "}") &
.subset2(i_parsed, "column") > j + 4L &
.subset2(i_parsed, "tex_group") == .subset2(i_parsed[j], "tex_group")))
i_parsed[lhs_start, char := "{\\frac{"]
i_parsed[rhs_end, char := "}}"]
}
res <- paste0(i_parsed[["char"]], collapse = "")
res <- gsub("\\over", "}{", res, fixed = TRUE)
out[i] <- res
}
}
out
}
产生的LaTeX文档:具有必要的LaTeX特定内容,以及内联分数的强制数学模式。 $5 \over 2$
This is another fraction: ${1 \over 2}$.
And another:
$$A = a \over b$$
What about:
$${{D \over C} \over H}$$
Finally:
$${e^{2c} \over x-1}$$
${2yz\over 1+x^{2} }$
$$\phi = 1 + {1 \over {1 + {1 \over {1 + {1 \over {1 + \ddots}}}}}}$$
\item $Dom\left(Q\right)\ne {\rm R}^{2} $ y uno de los puntos no pertenecientes al dominio es $\left({1\over 2} ,{1\over 2}\right).$
\bye
writeLines(over2frac(readLines("tex1.tex"), verbose = FALSE), "latex1.tex")