Google Apps Script Regex exec()返回null [英] Google Apps Script Regex exec() returning null

查看:94
本文介绍了Google Apps Script Regex exec()返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在调试模式下运行下面的代码时,我在for循环的第一次迭代中得到期望值,但在图像上看到第二次为null: > 第一次迭代:



第二次迭代



我的东西错了什么?

我使用的是:

  var newer_than ='newer_than:2d'; //添加用于更快的调试
var subjectIdentifier ='Ingress Portal提交:';
var searchString ='subject:'+ subjectIdentifier + newer_than;

函数getPortalName(字符串){
var myRegexp = /:(。+)/ g;
var match = myRegexp.exec(string);
var portalName = match [1];
返回portalName;
}

函数getPortalsSubmitted(){
var threads = GmailApp.search(searchString);
for(i = 0; i< threads.length; i ++){
var subject = threads [i] .getFirstMessageSubject();

var portalName = getPortalName(subject);
var subDate = threads [i] .getMessages()[0] .getDate();

Logger.log([portalName,subDate]);



函数updatePortals(){
var threads = GmailApp.search('subject:Ingress Portal'');
for(i = 0; i< threads.length; i ++){
Logger.log(threads [i] .getFirstMessageSubject());
}
}


解决方案

这个问题已经在评论中得到了回答,我会做出正确的回答。



理解这个问题的一个重要问题是在 exec 行为时正则表达式具有 g 标志。哪个按顺序调用会尝试查找下一个匹配,即使您传递了不同的字符串。这是文档链接。尽管MDN声明你应该小心不要重新创建RegExp对象(甚至是文字),因为它可能会重置 lastIndex 属性。至少在Apps脚本中是不正确的。如果正确地在代码中使用正则表达式,Apps Script会缓存正则表达式并重新使用同一个对象。



这两个效果合并意味着你在不知不觉中触发了你的代码上的这种下一次匹配行为。



最简单的解决方案就是放弃 g 标志,因为你不需要它(你只获得第一个结果)。但你也可以通过用 var myRegexp = new RegExp(')替换 var myRegexp = /:(。+)/ g; :(。+)','g'); ,迫使Apps Script给你一个新的对象。



我们可以从中学习到:如果你不需要它,不要使用标志。有时候我们很懒,并且不加思索地设置标志,以防万一。


When I run the code below in debug mode I get the expected value on the first iteration of the for loop but null on the second as seen on the images:

First iteration:

Second iteration:

What am I dong wrong?

The code I am using is:

var newer_than = ' newer_than:2d'; //added for faster debugging
var subjectIdentifier = '"Ingress Portal Submitted: "';
var searchString = 'subject:'+subjectIdentifier+newer_than;

function getPortalName(string) {
  var myRegexp = /: (.+)/g;
  var match = myRegexp.exec(string);
  var portalName = match[1];
  return portalName;
}

function getPortalsSubmitted() {
  var threads = GmailApp.search(searchString);
  for (i=0; i<threads.length; i++) {
    var subject = threads[i].getFirstMessageSubject();

    var portalName = getPortalName(subject);
    var subDate = threads[i].getMessages()[0].getDate();

    Logger.log([portalName,subDate]);
  }
}

function updatePortals() {
  var threads = GmailApp.search('subject:"Ingress Portal"');
  for (i=0; i<threads.length; i++) {
    Logger.log(threads[i].getFirstMessageSubject());
  }
}

解决方案

Although this question was already answered on the comments, I'll make a proper answer.

One important issue to understand this problem is on the exec behavior when the regex have the g flag. Which, when called sequentially will try to look for the "next" match, even if you pass on a different string. Here is the documentation link on MDN.

And although MDN states that you should take care not to re-create the RegExp object (even a literal), because it might reset the lastIndex property. At least in Apps Script that's not true. If a regex literal is used in the exact same spot in the code over and over, Apps Script caches the regex and re-uses the same object.

This two effects combined meant you were triggering this "next match" behavior on your code unknowingly.

The easiest solution for you is to just drop the g flag, since you don't need it anyway (you're getting only the first result). But you could have also fixed this by replacing the var myRegexp = /: (.+)/g; line with var myRegexp = new RegExp(': (.+)','g');, forcing Apps Script to give you a new object.

I think a good lesson we can learn from this is: don't use a flag if you don't need it. Sometimes we're lazy and set flags without thinking, "just in case".

这篇关于Google Apps Script Regex exec()返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆