【问题标题】:Regular expression to extract valid cell references from a spreadsheet formula从电子表格公式中提取有效单元格引用的正则表达式
【发布时间】:2014-02-07 13:56:08
【问题描述】:

我正在尝试使用 Google Apps 脚本 (Javascript) 从电子表格公式中提取有效的单元格引用和范围引用。

有效的单元格引用是一个或两个字母,后跟不以零开头的连续数字。字母或数字前面可能有也可能没有 $ 字符。整个引用不能以字母、数字或下划线(在这种情况下,它可能是电子表格函数或命名范围名称的一部分)或冒号(在这种情况下,它可能是范围参考)。

范围引用正则表达式 (rangeRefRe) 似乎运行良好;但我的单元格引用正则表达式 (cellRefRe) 找不到匹配项。如果有人能指出我做错了什么,那就太好了。

function myFunction()
{
  var formula = '=A100+B$2:2+INDIRECT("A2:B")+$C3-SUM($D$1:$E5)';
  var fSegments = formula.split('"'); // I want to exclude references within double quotation marks
  var rangeRefRe = /[^0-9a-zA-Z_$]([0-9a-zA-Z$]+?:[0-9a-zA-Z$]+)(?![0-9a-zA-Z_])/g;
  var cellRefRe = /[^0-9a-zA-Z_$:](\${,1}[a-zA-Z]{1,2}\${,1}[1-9][0-9]*)(?![0-9a-zA-Z_:])/g;
  var refResult;
  var references = [];
  for (var i = 0; i < fSegments.length; i += 2)
  {
    while (refResult = rangeRefRe.exec(fSegments[i]))
    {
      references.push(refResult[1]);
    }
    while (refResult = cellRefRe.exec(fSegments[i]))
    {
      references.push(refResult[1]);
    }
  }
  Logger.log(references);
}

【问题讨论】:

    标签: javascript regex google-apps-script google-sheets


    【解决方案1】:

    我在R 中一直在做同样的事情,并认为我会添加我的方法。它包括对外部工作簿的引用。我没有包括 B$2:2 这样的东西,因为我从未在野外见过它们。

    # Thanks to https://www.get-digital-help.com/2017/02/07/extract-cell-references-from-a-formula/
    library(stringr)
    formula <- "=data!A100+'[C:\\temp dir\\book.xlsx]Sheet 1'!$C3-SUM($D$1:$E5)"
    book <- "\\[[a-zA-Z0-9][a-zA-Z0-9\\s\\+\\-\\&\\_\\.\\:\\\\]*\\]" # add any needed filepath characters
    sheet <- "[a-zA-Z][a-zA-Z0-9\\s\\+\\-\\&\\_\\(\\)]*" # add any needed sheetname characters
    range <- "\\$?[A-Z]+\\$?[0-9]+(:\\$?[A-Z]+\\$?[0-9]+)?(?!\\()" # not followed by (
    pattern <- paste0("('?((", book, ")?", sheet, ")'?!)?", range)
    pattern
    #> [1] "('?((\\[[a-zA-Z0-9][a-zA-Z0-9\\s\\+\\-\\&\\_\\.\\:\\\\]*\\])?[a-zA-Z][a-zA-Z0-9\\s\\+\\-\\&\\_\\(\\)]*)'?!)?\\$?[A-Z]+\\$?[0-9]+(:\\$?[A-Z]+\\$?[0-9]+)?"
    str_extract_all(formula, pattern, simplify=TRUE) # matrix
    #>      [,1]        [,2]                                     [,3]      
    #> [1,] "data!A100" "'[C:\\temp dir\\book.xlsx]Sheet 1'!$C3" "$D$1:$E5"
    

    reprex package (v0.2.1) 于 2019 年 3 月 14 日创建

    【讨论】:

      【解决方案2】:

      Josh Dawson 对正则表达式 posted 的变体以包含工作表名称。

      var formula = '=data!A100+B$2:2+INDIRECT("A2:B")+\'Sheet 1\'!$C3-SUM($D$1:$E5)';
      var fSegments = formula.split('"'); // I want to exclude references within double quotation marks
      var re = /[^0-9a-zA-Z_$:]((((\'.+\')|([a-zA-Z0-9]+))\!)?\$?([a-zA-Z]+(\$?[1-9]\d*)(:(\$?[a-zA-Z]+)?\$?([1-9]\d*)?)?|((:\$?[a-zA-Z]+\$?([1-9]\d*)?))))/g;
      var refResult;
      var references = [];
      for (var i = 0; i < fSegments.length; i += 2) {
        while (refResult = re.exec(fSegments[i])) {
          references.push(refResult[1]);
        }
      }
      console.log(references);

      【讨论】:

        【解决方案3】:

        问题和答案非常有帮助,但我遇到了一些问题,所以这里有一些注意事项供未来的读者参考:

        1. 最好将“(”添加到正则表达式不能以结尾的字符。公式可以包含对名为“a1”或类似名称的自定义函数的调用。添加左括号可以防止匹配对此类名称错误的自定义函数的调用。

        2. 虽然“A2:A”和“A1:2”是有效范围,但“A:2”等范围不是。

        3. 我需要按照它们在公式中出现的方式排序的引用。范围和单元格的单个正则表达式可以解决这个问题。

        这是我想出的正则表达式:

        /[^0-9a-zA-Z_$:]\$?([a-zA-Z]+(\$?[1-9]\d*(:(\$?[a-zA-Z]+)?\$?([1-9]\d*)?)?|((:\$?[a-zA-Z]+\$?([1-9]\d*)?))))(?![0-9a-zA-Z_(])/g;

        【讨论】:

          【解决方案4】:

          正确的正则表达式应该是:

          /[^0-9a-zA-Z_$:](\$?[a-zA-Z]{1,2}\$?[1-9][0-9]*)(?![0-9a-zA-Z_:])/
          

          【讨论】:

            【解决方案5】:

            JavaScript 不支持这部分正则表达式:{,1}。要允许 0 或 1 次出现,它需要是 {0,1},或者您可以将其替换为 ?

            /[^0-9a-zA-Z_$:](\$?[a-zA-Z]{1,2}\$?[1-9][0-9]*)(?![0-9a-zA-Z_:])/g;
            

            【讨论】:

            • 非常感谢。我什至还打开了一个显示 Javascript 支持的正则表达式参考网站。 :-( 但无论如何我只需要 ? 量词。
            • 不客气。请注意,我说“JavaScript 不支持”是因为其他正则表达式实现可能允许它,但我很确定我编写的其他语言也没有接受它。在{m,n} 格式中可以省略n,所以{3,} 表示“至少3”,但不能省略m...
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-01-12
            • 2018-01-10
            • 1970-01-01
            • 1970-01-01
            • 2015-03-24
            • 1970-01-01
            • 2015-01-05
            相关资源
            最近更新 更多