Javascript 谷歌应用程序脚本-类型错误:无法读取属性;1“;从零开始

Javascript 谷歌应用程序脚本-类型错误:无法读取属性;1“;从零开始,javascript,arrays,regex,google-apps-script,null,Javascript,Arrays,Regex,Google Apps Script,Null,我编写了一个谷歌应用程序脚本,从我的电子邮件中提取一些数据,并将其插入电子表格。脚本实际上运行得很好,插入数据也很好,但我的日志中不断出现以下错误: TypeError:无法从null读取属性“1”。(第46行,文件“代码”) ,则exec方法返回一个数组,其中“匹配的文本作为第一项,然后每个捕获括号对应一项,该括号包含捕获的文本。”由于我希望正则表达式的括号内的值,而不是整个匹配的文本,因此我使用[1] 下面是有问题的函数: function getEmails() { var label

我编写了一个谷歌应用程序脚本,从我的电子邮件中提取一些数据,并将其插入电子表格。脚本实际上运行得很好,插入数据也很好,但我的日志中不断出现以下错误:

TypeError:无法从null读取属性“1”。(第46行,文件“代码”)

,则
exec
方法返回一个数组,其中“匹配的文本作为第一项,然后每个捕获括号对应一项,该括号包含捕获的文本。”由于我希望正则表达式的括号内的值,而不是整个匹配的文本,因此我使用
[1]

下面是有问题的函数:

function getEmails() {
  var label = GmailApp.getUserLabelByName("CapitalOne Transaction");
  var threads = label.getThreads(); // Get threads of label above
  for (var i in threads) {
    var messages = threads[i].getMessages();
    for (var j in messages) {
      if ( messages[j].isUnread() ) {
        var emailBody = messages[j].getPlainBody();
        Logger.log("Email body: " + emailBody);

        // Get account number
        const regExpAcct = /Account ending in (\d{4})/g;
        var message_account = regExpAcct.exec(emailBody);
        if(message_account){ Logger.log("Email message accnt: " + message_account[1]); }

        // Get date of transaction
        var regExpDate = /we're notifying you that on (...+), at/g;
        var message_date = regExpDate.exec(emailBody);
        if(message_date){ Logger.log("Email message date: " + message_date[1]); }

        // Get vendor name
        var regExpVendor = /, at (...+),/g;
        var message_vendor = regExpVendor.exec(emailBody);
        if(message_vendor){ Logger.log("Email message vendor: " + message_vendor[1]); }

        // Get transaction amount
        const regExpAmount = /purchase in the amount of \$(\S+) was/g;
        var message_amount = regExpAmount.exec(emailBody);
        if(message_amount){ Logger.log("Email message amount: " + message_amount[1]); }

        addDataToSpreadsheet( message_date[1], message_account[1], message_vendor[1], message_amount[1] );
        messages[j].markRead();
      }
    }
  }
}
问题中的第(46)行是这样的:
addDataToSpreadsheet(消息日期[1],消息帐户[1],消息供应商[1],消息金额[1])

它调用此函数:

function addDataToSpreadsheet( date, account, vendor, amount ) {
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.appendRow( [date, account, vendor, amount] );
}
var emailBody = messages[j].getPlainBody();
Logger.log("Email body: " + emailBody);
var message_account = "", message_date = "", message_vendor = "", message_amount = "";

// Get account number
const regExpAcct = /Account ending in (\d{4})/;
var message_account_m = regExpAcct.exec(emailBody);
if(message_account_m){ message_account = message_account_m[1]; Logger.log("Email message accnt: " + message_account); }
// Get date of transaction
var regExpDate = /we're notifying you that on (...+), at/;
var message_date_m = regExpDate.exec(emailBody);
if(message_date_m){ message_date = message_date_m[1]; Logger.log("Email message date: " + message_date); }

// Get vendor name
var regExpVendor = /, at (...+),/;
var message_vendor_m = regExpVendor.exec(emailBody);
if(message_vendor_m){ message_vendor = message_vendor_m[1]; Logger.log("Email message vendor: " + message_vendor); }

// Get transaction amount
const regExpAmount = /purchase in the amount of \$(\S+) was/;
var message_amount_m = regExpAmount.exec(emailBody);
if(message_amount_m){ message_amount = message_amount_m[1]; Logger.log("Email message amount: " + message_amount); }

addDataToSpreadsheet( message_date, message_account, message_vendor, message_amount);
messages[j].markRead();
我的
Logger.log
s在每个正则表达式都输出变量之后,正如我所说的,数据正通过上面的函数完美地输入到电子表格中,但是每次运行
getEmails()
函数时,我仍然会得到错误


知道为什么吗?

很明显,其中一个regexp不匹配,当您尝试访问此类匹配的Group 1值时,会出现异常。我建议将这些值分配给单独的变量,稍后使用它们传递到
addDataToSpreadsheet
函数:

function addDataToSpreadsheet( date, account, vendor, amount ) {
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.appendRow( [date, account, vendor, amount] );
}
var emailBody = messages[j].getPlainBody();
Logger.log("Email body: " + emailBody);
var message_account = "", message_date = "", message_vendor = "", message_amount = "";

// Get account number
const regExpAcct = /Account ending in (\d{4})/;
var message_account_m = regExpAcct.exec(emailBody);
if(message_account_m){ message_account = message_account_m[1]; Logger.log("Email message accnt: " + message_account); }
// Get date of transaction
var regExpDate = /we're notifying you that on (...+), at/;
var message_date_m = regExpDate.exec(emailBody);
if(message_date_m){ message_date = message_date_m[1]; Logger.log("Email message date: " + message_date); }

// Get vendor name
var regExpVendor = /, at (...+),/;
var message_vendor_m = regExpVendor.exec(emailBody);
if(message_vendor_m){ message_vendor = message_vendor_m[1]; Logger.log("Email message vendor: " + message_vendor); }

// Get transaction amount
const regExpAmount = /purchase in the amount of \$(\S+) was/;
var message_amount_m = regExpAmount.exec(emailBody);
if(message_amount_m){ message_amount = message_amount_m[1]; Logger.log("Email message amount: " + message_amount); }

addDataToSpreadsheet( message_date, message_account, message_vendor, message_amount);
messages[j].markRead();
现在,所有四个变量——
message\u account
message\u date
message\u vendor
message\u amount
——都分配了一个空字符串。即使正则表达式失败,并且没有为它们中的任何一个分配Group 1值,当在代码后面引用它们时,它们在调用时也不会导致错误,因为它们被分配了一些值


请注意,由于您没有迭代匹配项,
/g
修饰符是不必要的。

太好了。工作得很有魅力。这样做后没有错误。你能解释一下(可能会添加到未来谷歌的答案中)为什么只将
message\u amount\u m[1]
放入它自己的单独变量(
message\u amount
)中,以便在
addDataToSpreadsheet()
中使用,而不是
addDataToSpreadsheet(message\u date\u m[1],message\u account\u m[1],消息_vendor_m[1],消息_amount_m[1])?我从每个正则表达式中得到了正确的值,所以它们匹配得很好。@dmoz我补充了一些解释。我认为是JS引擎中的某些行为导致了故障。由于计算机以二进制数为基础进行逻辑运算,我们用类似英语的语言编写了我们的代码,有一段时间乘以两个浮点会产生意想不到的结果,我们称之为近似不精确的结果,为了克服这个问题,我们确实相应地改变了我们的逻辑,这是类似的情况,所以我们的朋友找到了一个解决方案,但如果您有适当的异常或错误处理,问题就会被注意到。可能JS引擎无法通过索引检测数组元素的类型。通过使用另一个变量,它将它们转换为基元类型,JavaScript中的数组和对象基本上是一些指针,它们被认为是一个复杂的对象。