r - 在数学表达式中用 C 的 pow 语法替换 ^(幂)符号

标签 r regex

我有一个数学表达式,例如:

((2-x+3)^2+(x-5+7)^10)^0.5

我需要更换 ^符号到pow C语言的功能。我认为正则表达式是我需要的,但我不知道像专业人士那样的正则表达式。所以我最终得到了这个正则表达式:
(\([^()]*)*(\s*\([^()]*\)\s*)+([^()]*\))*

我不知道如何改进这一点。你能给我一些建议来解决这个问题吗?

预期输出:
pow(pow(2-x+3,2)+pow(x-5+7,10),0.5)

最佳答案

R 最奇妙的地方之一是您可以轻松地使用 R 操作 R 表达式。在这里,我们递归遍历您的表达式并替换 ^ 的所有实例。与 pow :

f <- function(x) {
  if(is.call(x)) {
    if(identical(x[[1L]], as.name("^"))) x[[1L]] <- as.name("pow")
    if(length(x) > 1L) x[2L:length(x)] <- lapply(x[2L:length(x)], f)
  }
  x
}
f(quote(((2-x+3)^2+(x-5+7)^10)^0.5))

## pow((pow((2 - x + 3), 2) + pow((x - 5 + 7), 10)), 0.5)

这应该比正则表达式更健壮,因为您依赖于 R 语言的自然解释,而不是依赖于可能全面也可能不全面的文本模式。

详情 :R 中的调用存储在类似列表的结构中,函数/运算符位于列表的开头,参数位于以下元素中。例如,考虑:
exp <- quote(x ^ 2)
exp
## x^2
is.call(exp)
## [1] TRUE

我们可以用 as.list 检查调用的底层结构。 :
str(as.list(exp))
## List of 3
##  $ : symbol ^
##  $ : symbol x
##  $ : num 2

如您所见,第一个元素是函数/运算符,后续元素是函数的参数。

所以,在我们的递归函数中,我们:
  • 检查一个对象是否是一个调用
  • 如果是:检查是否是对 ^ 的调用函数/运算符通过查看调用中的第一个元素 identical(x[[1L]], as.name("^")
  • 如果是:用 as.name("pow") 替换第一个元素
  • 然后,无论这是否是对 ^ 的调用或其他任何东西:
  • 如果调用有其他元素,循环遍历它们并将此函数(即 recurse )应用于每个元素,将结果替换回原始调用( x[2L:length(x)] <- lapply(x[2L:length(x)], f) )
  • 如果不是:只返回对象不变

  • 请注意,调用通常包含函数名称作为第一个元素。您可以使用 as.name 创建这些名称.名称在 R 中也被称为“符号”(因此输出 str)。

    关于r - 在数学表达式中用 C 的 pow 语法替换 ^(幂)符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40606723/

    相关文章:

    r - R中确定 'true'地址位置的方法

    r - 如何检查R中的两个文件

    arrays - 从 R 中的数据框创建三维数组

    javascript - 选择接下来的 2 位以 XXX 开头但不是 XXX 的数字

    r - 基于组和时间的值的共现(矩阵)

    python - rpy2 找不到已安装的外部 R 包

    regex - 在多列文件中 - 从 Bash 中的小数中删除所有尾随 0

    python - 为什么我找不到与 python 正则表达式匹配的所有模式?

    python - 通过 `re.split` 直接(在 Python 中)分隔每两个相邻不同数字之间的字符串?

    用于邮政信箱验证的 Java 正则表达式