Google Script: Match RegEx into 2D array

倖福魔咒の 提交于 2020-04-16 05:47:49

问题


I'm trying to extract information from Gmail into Google Spreadsheet. The information in the email has a table structure with the following columns List of Products, QTY Sold and the Subtotal for each product. These repeat N times.

When accesing the information using message.getPlainBody() I get the following text:


Product
Quantity
Price
Chocolate
1
$8.58
Apples
2
$40.40
Bananas
1
$95.99
Candy
1
$4.99
Subtotal:
$149.96

Progress

First I tried to use a regular expression to identify each row with all his elements:

  • Product name: Any amount of characters that don't include ':' (.*)[^:]
  • QTY Sold: Any number \d*
  • Anything that looks like a SubTotal [$]\d*.\d*

Wrapping everything up it looks like this

    function ExtractDetail(message){
      var mainbody = message.getPlainBody();

     //RegEx
     var itemListRegex = new RegExp(/(.*)[^:][\r\n]+(\d*[\r\n]+[$](\d*\.\d*)[\r\n]+/g);
     var itemList = mainbody.match(itemListRegex);
     Logger.log(itemList);
    }

And so far it works:

itemList: Chocolate 1 $8.58 ,Apples 2 $40.40 ,Bananas 1 $95.99 ,Candy 1 $4.99

However, I'm getting the following result:

  • [Chocolate 1 $8.58]
  • [Apples 2 $40.40]
  • [Bananas 1 $95.99]
  • [Candy 1 $4.99]

Instead of:

  • [Chocolate] [ 1 ] [$8.58]
  • [Apples] [ 2 ] [$40.40]
  • [Bananas] [ 1 ] [$95.99]
  • [Candy] [ 1 ] [$4.99]

Question

My question is, how can I append a new row in a way that it each row corresponds to each match found and that each column corresponds to each property?

How do I turn the result of each match into an array? Is it possible or should I change my approach?

Update:

Since the result of my current attemp is a large string I'm trying to find other options. This one poped up:

var array = Array.from(mainbody.matchAll(itemListRegex), m => m[1]);

Source: How do you access the matched groups in a JavaScript regular expression?

I'm still working on it. I still need to find how to add more columns and for some reason it starts on 'Apples' (following the examples), leaving 'Chocolates' behind.

Log:

Logger.log('array: ' + array);


回答1:


If you want to use matchAll like Array.from(mainbody.matchAll(itemListRegex), m => m[1]), how about this modification? Please think of this as just one of several possible answers.

In this case, /(.*[^:])[\r\n]+(\d*)[\r\n]+([$]\d*\.\d*)[\r\n]/g is used as the regex.

Modified script:

const itemListRegex = /(.*[^:])[\r\n]+(\d*)[\r\n]+([$]\d*\.\d*)[\r\n]/g;
var array = Array.from(mainbody.matchAll(itemListRegex), ([,b,c,d]) => [b,Number(c),d]);

Result:

[
  ["Chocolate",1,"$8.58"],
  ["Apples",2,"$40.40"],
  ["Bananas",1,"$95.99"],
  ["Candy",1,"$4.99"]
]
  • The result is the same with TheMaster's answer.

Test of script:

const mainbody = `
Product
Quantity
Price
Chocolate
1
$8.58
Apples
2
$40.40
Bananas
1
$95.99
Candy
1
$4.99
Subtotal:
$149.96
`;

const itemListRegex = /(.*[^:])[\r\n]+(\d*)[\r\n]+([$]\d*\.\d*)[\r\n]/g;
var array = Array.from(mainbody.matchAll(itemListRegex), ([,b,c,d]) => [b,Number(c),d]);
console.log(array)

Note:

  • About how can I append a new row in a way that it each row corresponds to each match found and that each column corresponds to each property?, this means for putting the values to Spreadsheet? If it's so, can you provide a sample result you expect?

References:

  • matchAll()
  • Array.from()



回答2:


Map and split the resulting array by \new lines:

const data = `Product
Quantity
Price
Chocolate
1
$8.58
Apples
2
$40.40
Bananas
1
$95.99
Candy
1
$4.99
Subtotal:
$149.96`;

const itemListRegex = /.*[^:][\r\n]+\d*[\r\n]+\$\d*\.\d*(?=[\r\n]+)/g;
const itemList = data.match(itemListRegex);

console.info(itemList.map(e => e.split(/\n/)));//map and split


来源:https://stackoverflow.com/questions/61022214/google-script-match-regex-into-2d-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!