【问题标题】:Extracting numbers from Gmail messages using Google Apps Script使用 Google Apps 脚本从 Gmail 邮件中提取数字
【发布时间】:2016-08-30 04:51:34
【问题描述】:

我正在尝试使用 Google Apps 脚本从我的 Gmail 邮件中提取如下所列的数字。

2,495.00
1,594
3,777.23
642.00

这是代码:

function myFunction() {

  var sheet = SpreadsheetApp.getActiveSheet();
  var threads = GmailApp.search('subject:(Transaction) after:2016/7/31 before:2016/8/10');

  for (var i=0; i<threads.length; i++)
  {
    var messages = threads[i].getMessages();
    var tmp;

    for (var j=0; j<messages.length; j++)
    {
      var content = messages[j].getBody();
      var subject = messages[j].getSubject();
      var date = messages[j].getDate();
      Logger.log(content);

      if (content)
      {
        tmp = content.match(/\d+(,\d+)*(\.\d+(e\d+)?)?/);
        var number = (tmp && tmp[j]) ? tmp[j] : 'No number';
        sheet.appendRow([number, subject, date]);
      }
      else
      {
        sheet.appendRow([content, subject, date]);
      }

    }
  }
}

我得到的结果好坏参半。对于某些消息,这按预期工作,但对于某些消息,它完全跳过消息中的数字。我是 JS/GAS 的新手,我认为问题出在正则表达式中,但我不确定。对此的任何帮助将不胜感激。

【问题讨论】:

  • 你需要带逗号的数字吗?
  • 如果是,请尝试:/(\d+,?\d+(?:\.\d+)?)/g

标签: javascript regex google-apps-script


【解决方案1】:

你在这里面临两个麻烦:
您正在使用的正则表达式看起来没有经过优化(但是您正在查看的内容都不清楚,如果您还在查看看起来像 642.00 的数字,则不应找到像 1,594 这样的数字)。不过,您可以使用像 Shekhar Khairnar 在评论中提出的正则表达式或类似的东西(最后的 g 很重要,因为您的邮件中有多个数字)。
第二个麻烦在var number = (tmp &amp;&amp; tmp[j]) ? tmp[j] : 'No number'; 行。为什么这一行有jvar? j是对 for 循环的引用 --> 消息的数量,与您的消息中出现的次数无关。
我能给你的建议是这样的:

function myFunction() {

  var sheet = SpreadsheetApp.getActiveSheet();
  var threads = GmailApp.search('test');
  var re = /(?:\d{1,3}[,])*\d{1,3}\.{0,1}\d{1,3}/g;

  for (var i=0; i<threads.length && i<5; i++) // added a condition because I didn't wanted to have too many results
  {
    var messages = threads[i].getMessages();
    var tmp;

    for (var j=0; j<messages.length; j++)
    {
      var content = messages[j].getPlainBody(); //.getBody();
      var subject = messages[j].getSubject();
      var date = messages[j].getDate();
      //Logger.log(content);

      if (content)
      {
        tmp = content.match(re); // /\d+(,\d+)*(\.\d+(e\d+)?)?/);
        var number = tmp || ['No number']; // result of tmp is either null or an array --> if it's null then it will take the value 'no number'
        Logger.log(number);
        sheet.appendRow([number.join(" | "), subject, date]);
      }
      else
      {
        sheet.appendRow([content, subject, date]);
      }

    }
  }
}

【讨论】:

  • 这篇文章详细描述了你的挑战:stackoverflow.com/questions/5917082/… 它推荐这个正则表达式:(\d*\.?\d+|\d{1,3}(,\d{3 })*(\.\d+)?) 我认为您还希望使正则表达式匹配多行和全局,然后遍历所有匹配项,以获取正文中的所有数字。仔细阅读这篇文章,因为匹配数字是一个非常重要的问题,甚至这个正则表达式也匹配一些你可能不想包含的情况。
  • 感谢 Harold 和 alfiethecoder!这真的很有帮助!
  • 如何修改正则表达式以仅查找带小数的数字。这基本上会排除诸如1,524之类的数字
  • 尝试这样的事情:/(?:\d{1,3},)*\d{1,3}\.\d{2}/g 我个人使用这个网站regex101.com 来构建我的正则表达式
猜你喜欢
  • 2016-06-06
  • 2012-07-25
  • 1970-01-01
  • 2016-05-05
  • 2018-03-08
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多