Google App Script Regex exec() 仅在一个函数中返回 null

Posted

技术标签:

【中文标题】Google App Script Regex exec() 仅在一个函数中返回 null【英文标题】:Google App Script Regex exec() returns null only in one function 【发布时间】:2018-03-06 19:18:40 【问题描述】:

我正在编写一个 Google Apps 脚本,以根据我收到的工作自动电子邮件创建日历事件。我正在使用正则表达式来提取在 Google 日历中填充事件所需的信息。到目前为止,除了一个函数 getEndTime() 之外,我的一切都按预期运行,它应该找到工作的结束时间,但目前在任何时候调用它都会返回 null。我使用 exec() 的所有其他功能都可以正常工作。

我已经阅读了许多其他关于 exec() 返回 null 的问题,并修复了常见问题,例如在调用 exec() 之前删除“g”标签并将 lastIndex 重置为 0。我还使用带有 javascript 选项的 regex101.com 检查了我的正则表达式,它显示了我期望的文本匹配。

适用于 regex101 但不适用于我的代码的正则表达式是:

/(Substitute\s+Report\s+Times:\s+[0-9_ ]*:[0-9_ ]*\s+[A-Z_ ]*\s+-\s+)([0-9_ ]*:[0-9_ ]*\s+(AM|PM))(\r|\n)/

我的代码是:

function findJobs() 
//Searches Gmail for substitute jobs and creates an event on the calendar

  //Gets emails with 'NewJobs' label
  var label = GmailApp.getUserLabelByName("NewJobs");
  var threads = label.getThreads();
  for (var i = 0; i < threads.length; i++)

    var messages = threads[i].getMessages();
    Logger.log("Thread " + i);

    for (var j = 0; j < messages.length; j++) 
      Logger.log("Message " + j);

      //gets email body in plain text
      var body = messages[j].getPlainBody();
      Logger.log("Getting body..." + j);

      //gets school name
      var school = getSchool(body);
      Logger.log(school);

      //gets start time
      var starttime = getStartTime(body);
      Logger.log(starttime);

      //gets end time
      var endtime = getEndTime(body);
      Logger.log(endtime);

      //gets teacher name
      var teacher = getTeacher(body);
      Logger.log(teacher);

      //gets school address
      var address = getLocation(body);
      Logger.log(address);

      //gets date
      var startdate = getDate(body);
      Logger.log(startdate);

      CalendarApp.getDefaultCalendar().createEvent("Subbing - " + school, new Date(startdate + " " + starttime), new Date(startdate + " " + endtime), location: address, description: teacher);
      //threads[j].removeLabel(label);
    
  
  Logger.log("--Done--");


function getSchool(text)
  //Gets the school name from an assignment email

  //Regular expression for school name
  var regex = /(School\s+:\s+)([a-zA-Z0-9_ ]*)(\r|\n)/;
  regex.lastIndex = 0;
  var match = regex.exec(text)[2];

  return match;


function getDate(text)
  //Gets the start date from an assignment email

  //Regular expression for start date
  var regex = /(Date:\s+)([0-9_ ]*\/[0-9_ ]*\/[0-9_ ]*)(\r|\n)/;
  regex.lastIndex = 0;
  var match = regex.exec(text)[2];

  return match;


function getStartTime(text)
  //Gets the start time from an assignment email

  //Regular expression for start time
  var regex = /(Substitute\s+Report\s+Times:\s+)([0-9_ ]*:[0-9_ ]*\s+(AM|PM))/;
  regex.lastIndex = 0;
  var match = regex.exec(text)[2];

  return match;


function getEndTime(text)
  //Gets the end time from an assignment email

  //Regular expression for end time
  var regex = /(Substitute\s+Report\s+Times:\s+[0-9_ ]*:[0-9_ ]*\s+[A-Z_ ]*\s+-\s+)([0-9_ ]*:[0-9_ ]*\s+(AM|PM))(\r|\n)/;
  regex.lastIndex = 0;
  Logger.log("End Time reset index...");
  var match = regex.exec(text)[2];
  Logger.log("End Time exec...");

  return match;


function getTeacher(text)
  //Gets the teacher name from an assignment email

  //Regular expression for teacher name
  var regex = /(Teacher\s+:\s+)([a-zA-Z0-9_ ]*,[a-zA-Z0-9_ ]*)(\r|\n)/;
  regex.lastIndex = 0;
  var match = regex.exec(text)[2];

  return match;


function getLocation(text)
  //Gets the location from an assignment email

  //Regular expression for location
  var regex = /(Address:\s+)(.*)(\r|\n)/;
  regex.lastIndex = 0;
  var match = regex.exec(text)[2];

  return match;

这是我收到的一封典型电子邮件:

You have been assigned as a substitute for a job starting on 9/21/2017.
 The following are the details of the job:
*************
 Job Summary
*************
Starting On                : 9/21/2017
School                     : School Site
Title                      : Pre School Teacher
Teacher                    : Name, Teacher
Substitute                 : Name, Substitute
Confirmation #             : 123456

**********
 Job Days
**********
School

---------------------------------------
School Site
Date: 9/21/2017
Employee Times: 8:00 AM    - 3:30 PM
Substitute Report Times: 8:00 AM    - 3:30 PM

***********************************
School Contact Information
***********************************
School Site
-----------------------------------------------------------
Address: 123 Main Ave    Anytown , USA 555555
Phone: 5555555555
-----------------------------------------------------------
**********************
 Special Instructions
**********************



Please do not reply to this system generated message. If you need help or have additional questions, please send an email to abc@abc.com

Thank you for using the substitute assignment system. Powered by Aesop

【问题讨论】:

【参考方案1】:

您使用的模式似乎过于复杂。我不能确定是什么原因导致它失败,但我的猜测是最后的(\r|\n)(请注意,如果你真的想这样做,你可以直接输入[\r\n])。

试试这个模式:

Substitute Report Times:.+ - (\d1,2:\d1,2 [AP]M)

这假定结束时间之前总是有一个连字符和一个空格,从您提供的示例文本看起来就是这种情况。

【讨论】:

你的模式奏效了!我确实必须将索引从 2 更改为 1,但它确实有效!只是出于好奇,我尝试将 (\r|\n) 替换为 [\r\n],但仍然遇到相同的错误。我将稍微研究一下您的替换模式,看看我还能从中学到什么。谢谢! 抱歉,我不是说[\r\n] 会解决(\r|\n) 造成的问题;只是就它们将匹配的内容而言它们是同义词,但前者更简单且更便宜,因为它不会创建捕获组。每当您匹配一组单个字符中的一个时,方括号就是要走的路(有一些例外)。 好的,知道了!我仍然无法弄清楚我以前的模式的问题是什么,但至少它现在正在工作,而且我确实学到了一两件事关于格式化正则表达式的更好方法。再次感谢!

以上是关于Google App Script Regex exec() 仅在一个函数中返回 null的主要内容,如果未能解决你的问题,请参考以下文章

Google Apps Script e.namedValues 格式多项选择

如何从 Google OAuth 2.0 Playground 运行 Google App Script 功能 |调用者没有权限

Google App Script Web App GET 和 POST 请求被 CORS 策略阻止

在Google App Script中使用导入的模块

Google App Script Deploy as Web App 卡在 Fetching Data

如何收听Telegram Bot错误? (Google App Script + Webhooks)