regex - 替换格式化数字中的前导空格

标签 regex r format

我想将格式化数字字符串中的前导空格替换为 \phantom{...}命令,其中 ...与前导空格的长度相同。我能做的是:

x <- c(1, 1., 0.230, 10.1, 1000, 10000.12)
y <- format(round(x, 2), nsmall=2, big.mark="\\\\,", big.interval=3L)
gsub(" ", "\\\\phantom{ }", y)

但是,我更想要一个 \phantom{}适当长度的(例如 \phantom{ } 然后几个 \phantom{ }

更新

基于Arun的解决方案,我构建了这个函数来格式化R中的数字在 LaTeX 表格中对齐:

tabAlign <- function(x, nsmall=0L, digits=NULL,
                     flag.before="\\\\phantom{", flag.after="}", embrace="$",
                     big.mark="\\\\,", big.interval=3L, ...)
{
    x <- if(!is.null(digits)) round(x, digits=digits) else x
    x <- format(x, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
    x <- sub("^([ ]+)", paste0(flag.before, "\\1", flag.after), x) 
    paste0(embrace, x, embrace) 
}

现在,让我们用它做一些有用的事情。 tabAlign(x)给出:

[1] "$\\phantom{       }1.00$" "$\\phantom{       }1.00$"
[3] "$\\phantom{       }0.23$" "$\\phantom{      }10.10$"
[5] "$\\phantom{ }1\\,000.00$" "$10\\,000.12$"           

将其复制并粘贴到 LaTeX 文件中会发现对齐不正确。原因是big.mark 。本预留nchar(big.mark)=3空格(在 R 字符串中)。然而,在 LaTeX 中,这占用的空间要少得多,因此数字不再完美对齐。理想情况下,sub()因此命令必须采用 nchar(big.mark)考虑在内(对于任何给定的 big.mark )。

更新2

这是另一个更新,现在考虑了 DWin 的提示。

tabAlign <- function(x, nsmall=0L, digits=NULL,
                     flag="\\\\phantom{\\1}", embrace="$",
                     big.mark="\\\\,", big.interval=3L, ...)
{
    ## round (if digits is not NULL)
    x <- if(!is.null(digits)) round(x, digits=digits) else x
    ## determine those with/without big.mark (idea from prettyNum())
    y <- format(x, nsmall=nsmall, trim=TRUE)
    y.sp <- strsplit(y, ".", fixed=TRUE)
    B <- sapply(y.sp, `[`, 1L)
    ind.w.big.mark <- grep(paste0("[0-9]{", big.interval+1L, ",}"), B)
    ind.wo.big.mark <- setdiff(1:length(y), ind.w.big.mark)
    ## format the numbers
    x <- format(x, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
    ## substitute spaces
    z <- character(l <- length(x))
    n <- nchar(big.mark)
    for(i in seq_len(l)){
        z[i] <- if(i %in% ind.wo.big.mark) sub("^([ ]+)", paste0(flag, big.mark), x[i])
                else sub("^([ ]+)", flag, x[i])
    }
    ## embrace
    paste0(embrace, z, embrace)
}

唯一缺少的部分是替换 \phantom 中的所有空格。在 if()部分,但只有空格数 - n ,其中n <- nchar(big.mark) 。这如何在 sub() 中指定?

更新3

这是一个解决方案(但不太优雅......见下文):

tabAlign <- function(x, nsmall=0L, digits=NULL,
                     flag="\\\\phantom{\\1}", embrace="$",
                     big.mark="\\\\,", big.mark2="\\,", big.interval=3L, ...)
{
    ## round (if digits is not NULL)
    x <- if(!is.null(digits)) round(x, digits=digits) else x
    ## determine those with/without big.mark (idea from prettyNum())
    y <- format(x, trim=TRUE)
    y.sp <- strsplit(y, ".", fixed=TRUE)
    B <- sapply(y.sp, `[`, 1L)
    w.big.mark <- grep(paste0("[0-9]{", big.interval+1L, ",}"), B)
    wo.big.mark <- setdiff(1:length(y), w.big.mark)
    ## format the numbers
    x. <- if(length(wo.big.mark) > 0 && length(w.big.mark) > 0) {
        ## format but trim
        y <- format(x, trim=TRUE, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
        ## paste big.mark to all numbers without big.mark
        y[wo.big.mark] <- paste0(big.mark2, y[wo.big.mark])
        format(y, justify="right")
    } else { # either all numbers have big.mark or not
        format(x, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
    }
    z <- sub("^([ ]+)", flag, x.)
    ## embrace
    paste0(embrace, z, embrace)
}

x <- c(1, 1., 0.230, 10.1, 1000, 10000.12)
tabAlign(x)
tabAlign(x[1:4])
tabAlign(x[5:6])

如果我们只能指定 big.mark 那就更好了(也不是big.mark2)。

最佳答案

这能解决问题吗?最好显示所需的输出(以在测试表达式时确定输出)。感谢 DWin 的建议(见评论)。

sub("^([ ]+)", "\\\\phantom{\\1}", y)

()捕获匹配模式(这是从字符串开头开始的一堆连续空格),并且可以使用 \\1 插入此捕获的组。如果您有多个括号,则可以使用从\1 到\9 的反向引用插入每个捕获的组。

关于regex - 替换格式化数字中的前导空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14077014/

相关文章:

r - 在ggplot2中一起使用构面标签和 strip 标签

javascript通过使用正则表达式删除评论

( 和 = 之间的 R str_match 正则表达式

Ruby:如何转换字符串中的温度单位?

r - 在 boxplot r 中添加回归线

r - 如何使用 igraph 和 R 找到顶点的边?

c++ - 让 svn diff 在提交期间显示 C++ 函数

php - PHP < 5.3.0 中的 DateTime::createFromFormat

types - 使用 cfspreadsheet 读取列格式

angular - NoUiSlider - 如何自定义我的 pips 标签以具有字符串值?