在范围内使用时,带有正则表达式的Google表格自定义函数在交替行上失败

时间:2015-02-02 06:27:20

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

我刚刚写了一个简单的谷歌工作表功能来修复一些网址。当手动传递值数组时,此函数在浏览器中正常工作。从Google工作表调用时,每隔一行的功能失败。

这不是数据的问题,因为我可以使它适用于"失败"通过将公式向下移动一行,或者为每个单元格单独调用公式来实现行。我认为这可能是Google工作表中regex的问题。

var pattern = /^http:\/\/(.*\/\d\/.*)_(.*)\/(g\d+p.*)$/ig;

function encode(input) {
  if (!input) return "";
  if (input.map) {
    return input.map(encode);
  } else {
    try {
      // same error happens, at this location, w/ or w/o toString()
      var matches = pattern.exec(input.toString());
      return matches[1] + encodeURIComponent(matches[2]) + matches[3];
    } catch (e) {
      return "error=" + e.message + " value = [" + input + "] ";
    }
  }
}

编辑:为了让后来的人更清楚,当正则表达式在" else"之内时,这也会失败。子句:

else { 
     var matches = /^(http:\/\/.*\/\d\/.*_)(.*)(\/g\d+p.*)$/ig.exec(input.toString());
     ... continues as normal

对于交替的数据行,我收到以下错误消息:

error=Cannot read property "1" from null.  value =  [ http://... ]

我试过了:

  • 将正则表达式放在try{}
  • 将正则表达式放在encode{}函数
  • 编写两个单独的函数(一个用于执行1个值)

在失败的情况下,我有这样的数据:

  • A1-A8中包含网址
  • B1具有公式" = encode(A1:A8)"
  • B1,B3,B5,B7中的数据完美计算
  • B2,B4,B6,B8中的数据错误输出(我的错误消息显示)

将公式移至单元格" B2"并说=encode(A2:A8)导致所有"失败"要计算的行和其他失败的行!

2 个答案:

答案 0 :(得分:4)

简短的回答(正如你对OP的评论所证实的)是从正则表达式中删除最后的“g”(全局标志)。


  

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec

     

语法 regexObj.exec( str

     

参数 str 与正则表达式匹配的字符串。

     

...

     

如果正则表达式使用“g”标志,则可以使用exec()   方法多次在同一个字符串中查找连续匹配。   执行此操作时,搜索从指定的str的子字符串开始   正则表达式的lastIndex属性(test()也将提前   lastIndex属性)。

因此,当你打算继续在同一个字符串中搜索匹配时,你真的应该只包含全局标志。

至于为什么它在其他环境中有效,我不确定。事实上,从你离开的地方继续搜索似乎有点奇怪,即使你将exec应用于一个全新的字符串也是如此。也许GAS中的实施有点“关闭” - 有更多知识的人可能会对此发表评论。

答案 1 :(得分:1)

要详细说明我的评论,错误意味着matches为空或不存在,这可能意味着正则表达式找不到匹配项。因此,重要的是要看input 的值是否匹配或者确实不符合正则表达式的要求。

正则表达式执行以下操作:

^http:\/\/(.*\/\d\/.*)_(.*)\/(g\d+p.*)$

Regular expression visualization

Debuggex Demo,匹配文字:

http://whatever/3/some_thing/g4p/can be anything
^^^^^^^        ^^^    ^     ^^^^

因此,如果在URL中找不到以下任何内容,则不会返回任何匹配项:

  • 网址不以http://开头(例如, http s ://
  • 没有出现: /,一个数字,/
  • 没有_
  • 没有出现 /g,有些数字,p

您确定文本每次都符合所有这些要求吗?