检查字符值是否是有效的R对象名称

aL3*_*3xa 4 regex r naming-conventions

几个月前我问过类似的东西,但是我使用JavaScript检查提供的字符串是否是"有效"的R对象名称.现在我想通过使用除了R之外的任何东西来实现同样的目标.我想有一个非常好的方法来做这个,有一些整洁的(不那么)深奥的R函数,所以正则表达式在我看来是最后一道防线.有任何想法吗?

哦,是的,使用背蜱和东西被认为是作弊.=)

Jos*_*ien 11

编辑2013-1-9修复正则表达式.从John Chambers的"数据分析软件"第456页中提取的前一个正则表达式(巧妙地)是不完整的.(Htley Wickham)


这里有几个问题.一个简单的正则表达式可以用来识别所有语法有效的名字---但其中的一些名字(如ifwhile)的"保留",并且不能被分配到.

  • 识别语法上有效的名称:

?make.names 解释一个语法上有效的名称:

[...]由字母,数字和点或下划线字符组成,以字母或点开头,后面没有数字.诸如".2way"之类的名称无效[...]

这是相应的正则表达式:

  "^([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*$"
Run Code Online (Sandbox Code Playgroud)
  • 识别无保留的语法有效名称

要识别非保留名称,可以利用基函数make.names(),该函数从任意字符串构造语法上有效的名称.

    isValidAndUnreserved <- function(string) {
        make.names(string) == string
    }

    isValidAndUnreserved(".jjj")
    # [1] TRUE
    isValidAndUnreserved(" jjj")
    # [1] FALSE
Run Code Online (Sandbox Code Playgroud)
  • 把它们放在一起

    isValidName <- function(string) {
        grepl("^([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*$", string)
    }
    
    isValidAndUnreservedName <- function(string) {
        make.names(string) == string
    }
    
    testValidity <- function(string) {
        valid <- isValidName(string)
        unreserved <- isValidAndUnreservedName(string)
        reserved <- (valid & ! unreserved)
        list("Valid"=valid,
             "Unreserved"=unreserved,
             "Reserved"=reserved)
    }
    
    testNames <- c("mean", ".j_j", "...", "if", "while", "TRUE", "NULL",
                   "_jj", "  j", ".2way") 
    t(sapply(testNames, testValidity))
    
          Valid Unreserved Reserved
    mean  TRUE  TRUE       FALSE   
    .j_j  TRUE  TRUE       FALSE   
    ...   TRUE  TRUE       FALSE   
    if    TRUE  FALSE      TRUE    
    while TRUE  FALSE      TRUE    
    TRUE  TRUE  FALSE      TRUE    
    NULL  TRUE  FALSE      TRUE    
    _jj   FALSE FALSE      FALSE   
      j   FALSE FALSE      FALSE   # Note: these tests are for "  j", not "j"
    .2way FALSE FALSE      FALSE  
    
    Run Code Online (Sandbox Code Playgroud)

有关这些问题的更多讨论,请参阅以下注释中由@Hadley链接的r-devel线程.

  • @ al3xa:语法上讲,用`.`或`...`作为变量名称没有错.*解析器*赋予`...`一个特殊含义. (2认同)

Hon*_*Ooi 5

正如约什建议的那样,make.names可能是最好的解决方案.它不仅会处理奇怪的标点符号,还会标记保留字:

make.names(".x")   # ".x"
make.names("_x")   # "X_x"
make.names("if")   # " if."
make.names("function")  # "function."
Run Code Online (Sandbox Code Playgroud)