简体   繁体   English

Google Apps Script 中的正则表达式执行时间限制如何工作?

[英]How does the Regular expression execution time limit work in Google Apps Script?

TLDR:域名注册地址:

What is this arbitrary RegExp execution time limit, how long is it, and when does it apply (because it does not apply equally in all Google Apps Script contexts)?这个任意的 RegExp 执行时间限制是多少,它是多长时间,它何时适用(因为它在所有 Google Apps 脚本上下文中并不同等适用)? Also, why does it apply when there are already execution time limits for the entire script?另外,当整个脚本已经有执行时间限制时,为什么它适用?

Full Post:完整帖子:

I have suddenly hit the error我突然遇到错误

"Error: Regular expression operation exceeded execution time limit." “错误:正则表达式操作超出了执行时间限制。”

in Google Apps Script.在 Google Apps 脚本中。 I have hit this error while running a function using a custom menu on Google sheets that I created.我在使用我创建的 Google 工作表上的自定义菜单运行一个函数时遇到了这个错误。 This makes a brief UI which requests the use to input a spreadsheet url, and then runs a function using the provided url (and spreadsheet).这将创建一个简短的 UI,它请求用户输入电子表格 url,然后使用提供的 url(和电子表格)运行一个函数。

I have run this function before and it worked fine, but now I am getting this regular expression time limit error.我以前运行过这个函数,它运行良好,但现在我收到了这个正则表达式时间限制错误。 To be clear this script comes nowhere near the maximum time limit for script execution, it is only apparently that my regular expression is too long.需要明确的是,此脚本远未达到脚本执行的最大时间限制,很明显我的正则表达式太长了。 I have determined the line with the regular expression (which runs repeatedly and is usually fine and has worked up to this point) has no obvious flaws.我已经确定了正则表达式(重复运行并且通常很好并且一直工作到这一点)的行没有明显的缺陷。 It is a large regular expression, but the text is not very long.这是一个很大的正则表达式,但文本不是很长。 It failed on a 217 character text.它在 217 个字符的文本上失败。

Furthermore, I have discovered that the error does NOT occur, when I run the function equivalent from the Google Apps Script Editor (without the UI, which simply calls this same function from a Google Apps Script Library I created).此外,我发现错误不会发生,当我从 Google Apps 脚本编辑器运行等效的函数时(没有 UI,它只是从我创建的 Google Apps 脚本库调用相同的函数)。 To be clear I am certain that the variables and environment in the working execution are the same.需要明确的是,我确信工作执行中的变量和环境是相同的。 It completed in 8 seconds, parsed the same text, and used the same regular expression.它在 8 秒内完成,解析相同的文本,并使用相同的正则表达式。

This leads me to believe that there is an arbitrary time limit that is applied to regular expressions which applies either because the function has been called from a custom menu, the function briefly uses UI, or the function calls a library (or some combination of these).这让我相信有一个任意的时间限制适用于正则表达式,因为该函数是从自定义菜单中调用的,该函数短暂使用了 UI,或者该函数调用了一个库(或这些的某种组合) )。

What is this arbitrary RegExp execution time limit, how long is it, and when does it apply (because it does not apply equally in all Google Apps Script contexts)?这个任意的 RegExp 执行时间限制是多少,它是多长时间,它何时适用(因为它在所有 Google Apps 脚本上下文中并不同等适用)? Also, why does it apply when there are already execution time limits for the entire script?另外,当整个脚本已经有执行时间限制时,为什么它适用?

I haven't been able to find anything mentioning this specific error/time limit/quota on Google's documentation of Google Apps Script.我在 Google 的 Google Apps Script 文档中找不到任何提及此特定错误/时间限制/配额的内容。

To be clear, I have checked that they are using the UI script is using the correct library version (and development mode is on anyway, so it is using the most up to date version).需要明确的是,我已经检查过他们使用的 UI 脚本是否使用了正确的库版本(并且开发模式仍然处于开启状态,因此它使用的是最新版本)。 I have also confirmed that same functions are running with the same variables via console printing so I know the only difference is how the function is being called.我还确认通过控制台打印使用相同的变量运行相同的函数,所以我知道唯一的区别是函数的调用方式。

Here is the RegExp that breaks the time limit in one context but no the other, if you need it for some reason:如果您出于某种原因需要,这是在一个上下文中打破时间限制但在另一个上下文中没有打破时间限制的正则表达式:

/[\s\<\>]*\d+\s*(?:(?:l\s*f|linear\s*feet|lin\s*feet|lin\s*ft)|(?:s\s*f|square\s*feet|sq\s*\ft|sq\s*feet|sq)|(?:ea|each))(?:[\s\,]*\S+){0,7}\s*\,\s*(?:(?:(?:(?:remove|removal|(?:(?:^|\s)+rem(?:\s|\.|\:|\-|$))|(?:(?:^|\s)+rmv(?:\s|\.|\:|\-|$))))|(?:(?:encapsulate|encapsulation|(?:^|\s)+encp?(?:ap)?(?:$|\s|\.|\-|\:)+|(?:^|\s)+cap(?:$|\s|\.|\-|\:)+|(?:^|\s)+enp(?:$|\s|\.|\-|\:)+|(?:^|\s)+seal(?:$|\s|\.|\-|\:)+))|(?:enclose)))/gi

MCVE: MCVE:

Here is some text it failed on in one context but not in another:这是它在一种情况下失败但在另一种情况下失败的一些文本:

Storage and Mechanical Room 6 adjacent to Stage- 6 month AHERA 15 EA ACPFI RMV <Category: 3> Note: Middle of ceiling, 5 damaged fittings.存储和机械室 6 毗邻舞台 - 6 个月 AHERA 15 EA ACPFI RMV <类别:3> 注意:天花板中间,5 个损坏的配件。 RMV all. RMV 全部。 0 SF Fireproofing, Enclosure, Above ceiling tiles <Category: 3> See note 0 SF 防火、外壳、天花板上方的瓷砖 <类别:3> 见注释

To reproduce the failing context, in a Google Sheets Spreadsheet, create a custom menu using the script editor (as a document bound script), and click the "Test" button.要重现失败的上下文,请在 Google Sheets 电子表格中,使用脚本编辑器(作为文档绑定脚本)创建自定义菜单,然后单击“测试”按钮。

Container-bound Script Code:容器绑定脚本代码:

function onOpen(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Test Menu').addItem('Test', 'testFun').addToUi();
}

function testFun() {
  var regExp = /[\s\<\>]*\d+\s*(?:(?:l\s*f|linear\s*feet|lin\s*feet|lin\s*ft)|(?:s\s*f|square\s*feet|sq\s*\ft|sq\s*feet|sq)|(?:ea|each))(?:[\s\,]*\S+){0,7}\s*\,\s*(?:(?:(?:(?:remove|removal|(?:(?:^|\s)+rem(?:\s|\.|\:|\-|$))|(?:(?:^|\s)+rmv(?:\s|\.|\:|\-|$))))|(?:(?:encapsulate|encapsulation|(?:^|\s)+encp?(?:ap)?(?:$|\s|\.|\-|\:)+|(?:^|\s)+cap(?:$|\s|\.|\-|\:)+|(?:^|\s)+enp(?:$|\s|\.|\-|\:)+|(?:^|\s)+seal(?:$|\s|\.|\-|\:)+))|(?:enclose)))/gi;
  var text = 'Storage and Mechanical Room 6 adjacent to Stage- 6 month AHERA 15 EA ACPFI RMV <Category: 3> Note: Middle of ceiling, 5 damaged fittings. RMV all. 0 SF Fireproofing, Enclosure, Above ceiling tiles <Category: 3> See note';
  text.match(regExp);
  Logger.log('This line will not be reached because of error');
}

It also fails when running testFun() from the container-bound script in the script editor.在脚本编辑器中从容器绑定脚本运行testFun()时它也会失败。

To reproduce the successful execution context, create a standalone google apps script (not from the spreadsheet) and run testFun() in the script editor.要重现成功的执行上下文,请创建一个独立的 google 应用程序脚本(不是来自电子表格)并在脚本编辑器中运行testFun()

Standalone Script Code:独立脚本代码:

function testFun() {
  var regExp = /[\s\<\>]*\d+\s*(?:(?:l\s*f|linear\s*feet|lin\s*feet|lin\s*ft)|(?:s\s*f|square\s*feet|sq\s*\ft|sq\s*feet|sq)|(?:ea|each))(?:[\s\,]*\S+){0,7}\s*\,\s*(?:(?:(?:(?:remove|removal|(?:(?:^|\s)+rem(?:\s|\.|\:|\-|$))|(?:(?:^|\s)+rmv(?:\s|\.|\:|\-|$))))|(?:(?:encapsulate|encapsulation|(?:^|\s)+encp?(?:ap)?(?:$|\s|\.|\-|\:)+|(?:^|\s)+cap(?:$|\s|\.|\-|\:)+|(?:^|\s)+enp(?:$|\s|\.|\-|\:)+|(?:^|\s)+seal(?:$|\s|\.|\-|\:)+))|(?:enclose)))/gi;
  var text = 'Storage and Mechanical Room 6 adjacent to Stage- 6 month AHERA 15 EA ACPFI RMV <Category: 3> Note: Middle of ceiling, 5 damaged fittings. RMV all. 0 SF Fireproofing, Enclosure, Above ceiling tiles <Category: 3> See note';
  text.match(regExp);
  Logger.log('This line will be successfully reached');
}

Partial answer:部分答案:

  • The issue is reproducible in engine.该问题可在引擎中重现。
  • The issue doesn't seem to be reproducible in engine该问题似乎无法在引擎中重现

This seems to account for differences in execution context.这似乎解释了执行上下文的差异。 Given the deprecation of engine, It's unlikely that you find the exact limit or reason of the issue(But it seems to be around 300ms).鉴于引擎的弃用,您不太可能找到问题的确切限制或原因(但似乎在 300 毫秒左右)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM