【问题标题】:extract data from gmail add to spreadsheet- Google apps script从 gmail 中提取数据添加到电子表格 - Google 应用程序脚本
【发布时间】:2017-09-21 12:53:33
【问题描述】:

我已经搜索、复制和修改了代码,并试图分解其他人所做的事情,但我仍然无法做到这一点。

我有一个电子商务网站的电子邮件收据,我试图从每封电子邮件中收集特定的详细信息,并使用脚本保存到电子表格中。

这是我现在拥有的整个脚本。

function menu(e) {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('programs')
      .addItem('parse mail', 'grabreceipt')
      .addToUi();
}

function grabreceipt() {

  var ss = SpreadsheetApp.getActiveSheet();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getSheetByName("Sheet1");
  var threads = GmailApp.search("(subject:order receipt) and (after:2016/12/01)");
  var a=[];
  for (var i = 0; i<threads.length; i++)
  {
    var messages = threads[i].getMessages();

    for (var j=0; j<messages.length; j++)
    {
    var messages = GmailApp.getMessagesForThread(threads[i]);
    for (var j = 0; j < messages.length; j++) {
      a[j]=parseMail(messages[j].getPlainBody());
    }
  }
  var nextRow=s.getDataRange().getLastRow()+1;
  var numRows=a.length;
  var numCols=a[0].length;
  s.getRange(nextRow,1,numRows,numCols).setValues(a);
}

function parseMail(body) {
  var a=[];
  var keystr="Order #,Subtotal:,Shipping:,Total:";
  var keys=keystr.split(",");
  var i,p,r;
  for (i in keys)  {
    //p=keys[i]+(/-?\d+(,\d+)*(\.\d+(e\d+)?)?/);
    p=keys[i]+"[\r\n]*([^\r^\n]*)[\r\n]";
    //p=keys[i]+"[\$]?[\d]+[\.]?[\d]+$";
    r=new RegExp(p,"m");
    try {a[i]=body.match(p)[1];}
    catch (err) {a[i]="no match";}
  }
  return a;
}
}

因此,要从中提取的电子邮件数据仅以文本形式出现:

订单 #89076
(正文内容,省略)
小计:528.31 美元
运费:42.66 美元,通过 Priority Mail®
付款方式:支票付款-汇票
总计:570.97 美元

注意:我的网站订单 456。客户询问了这个和那个......等等。

原始代码正则表达式旨在抓取内容,遵循在他们自己的行中很容易找到的 keystr 值。所以这是有道理的:

p=keys[i]+"[\r\n]*([^\r^\n]*)[\r\n]";

这行得通,但是行中包含更多数据的结果,如行 Shipping: $42.66 via Priority Mail®。

我的数据更加混合,我只想取数字,或数字和小数。所以我有这个,而不是在 regex101.com 上验证

p=keys[i]+"[\$]?[\d]+[\.]?\d+$";

仅表达式 [\$]?[\d]+[.]?\d+$ 效果很好,但我仍然得到每一行的“不匹配”。

此外,在此搜索中返回了 22 个线程,并在电子表格中填充了 39 行。我不知道为什么是 39?

【问题讨论】:

  • 这个问题太冗长了,我会把它缩短到需要的程度。在这种情况下,它将是您在电子邮件中的示例字符串(至少 3-4 个示例)。你用来匹配它的正则表达式和你得到的结果。最后,提及您实际想要匹配的内容并要求输入以修改正则表达式。此外,问题的正则表达式标签将帮助您获得适当的受众。
  • 另外,如果您还没有这样做,我会使用regex101.com 等服务来帮助完善正则表达式。
  • 谢谢杰克。我接受了您的建议并修改了问题,另外我根据您在 regex101.com 上的建议进行了一些自己的试验。问题中提到,我成功匹配了我想要的新表达式,但结果比原始代码更差。
  • 这成为问题的一部分,当我对脚本进行更改时,得到不同(但不正确)的结果,然后将其改回并得到与第一轮不同的结果错误。当结果本身变成变量时,即使回到已知点,如何剔除特定的问题或变量?

标签: python regex google-apps-script gmail


【解决方案1】:

您的正则表达式无法正常工作的原因是您没有将您使用的字符串中的“\”转义为create the regex

所以像这样的正则表达式

"\s?\$?(\d+\.?\d+)"

需要像这样转义:

"\\s?\\$?(\\d+\\.?\\d+)"

下面的代码只是从您的 parseEmail() 修改为在这里作为 sn-p 工作。如果您将此复制到您的应用脚本代码中,请删除 document.getElementById() 行。

您可以在下面的 sn-p 中尝试您的示例,它只会给您数字。

function parseMail(body) {
 if(body == "" || body == undefined){
  var body = document.getElementById("input").value
  }
  var a=[];
  var keystr="Order #,Subtotal:,Shipping:,Total:";
  var keys=keystr.split(",");
  var i,p,r;
  for (i in keys)  {
    p=keys[i]+"\\s?\\$?(\\d+\\.?\\d+)";
    r=new RegExp(p,"m");
    try {a[i]=body.match(p)[1];}
    catch (err) {a[i]="no match";}
  }
  document.getElementById("output").innerHTML = a.join(";")
  return a;
}
<textarea id ="input"></textarea>
<div id= "output"></div>
<input type = "button" value = "Parse" onclick = "parseMail()">

希望有帮助

【讨论】:

  • 谢谢杰克,这非常有帮助,几乎解决了整个问题!然而,当我添加更改并运行它时,我仍然看到一些重复的行。比我以前得到的要少得多,但仍在发生。是否需要针对与此相关的其他问题开始一个新问题,还是可以继续进行进一步提问的线程?
  • 如果这回答了您的正则表达式问题,请开始一个新线程。将此标记为已接受谢谢!
猜你喜欢
  • 2015-12-29
  • 2021-10-19
  • 2013-09-13
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多