我正在尝试使用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不支持你的正则表达式的这一部分:{,1}
。要允许0或1次出现,它需要是{0,1}
,或者你可以用?
替换它:
/[^0-9a-zA-Z_$:](\$?[a-zA-Z]{1,2}\$?[1-9][0-9]*)(?![0-9a-zA-Z_:])/g;
问题和答案非常有用,但我遇到了一些问题,所以这里有一些未来读者的注意事项:
这是我提出的正则表达式:
/[^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;
正确的正则表达式应该是:
/[^0-9a-zA-Z_$:](\$?[a-zA-Z]{1,2}\$?[1-9][0-9]*)(?![0-9a-zA-Z_:])/
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);
我一直在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创建于2019-03-14(v0.2.1)