yuhtaryouko
@yuhtaryouko (Yuta Kato)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

正規表現での文字列抽出がうまくいかない

Q&A

Closed

解決したいこと

gasを使ってgmailに届いた本文から必要な項目を抽出し、スプレッドシートの該当セルに転記するということをしたいです。

発生している問題・エラー

正規表現を使って文字列検索をしているのですが、うまくできません。対象としているメール文章は以下の通りです。

メール画像.jpg

メール画像2.jpg

該当するソースコード

function myFunction() {

//メールの中から検索条件に合致したメールスレッドの検索//

  const threads= GmailApp.search('subject:"【楽天市場】注文内容ご確認(自動配信メール)" newer_than:30d' );
  Logger.log(threads);
  
  for (const thread of threads){
    Logger.log(thread);
    const messages = thread.getMessages();
    Logger.log(messages);

  for (const message of messages){
    Logger.log(message);

    const mail_body = message.getPlainBody()
    Logger.log(mail_body);

  //正規表現で必要な情報を入手 ※分からないこと1

    const reg_shop_name = new RegExp(/ショップ名 :(.*\r)/);
    const shop_name = mail_body.match(reg_shop_name);
    Logger.log(shop_name);
  
   ※分からないこと2 注文者を抽出するのにorder date という変数使ってるのはただのミスです
    const order_date = mail_body.match(/[注文者].*/);
    Logger.log(order_date);
    

  }  
  }
}

【正規表現による抽出結果】
メール画像3.jpg

分からないこと1
/ショップ名 :(.*\r)/ という正規表現で検索をしているのに、なぜ抽出結果が2つ出てくるのか。
(メールの最初に出てくるのは[ショップ名 :]という風にかっこがついているのにどうして?)

分からないこと2
/[注文者].*/で検索をして、なぜリターンが[注文情報が楽天市場のサーバに(以下略)]ということになるのか。
【注文者】で検索しているのになぜ【注文情報が】が抽出されるのかちんぷんかんぷんです…。

自分で試したこと

分からないこと1に関しては結果が2つ出てきてしまうので、仕方なく[shop_name[1]]として扱えばうまくできそうでした。
分からないこと2に関しては/注文者/に続く表現を色々変えてみましたがうまくいきませんでした。

初心者の質問・見苦しいコードですみません。

0

2Answer

分からないこと1
/ショップ名 :(.*\r)/ という正規表現で検索をしているのに、なぜ抽出結果が2つ出てくるのか。
(メールの最初に出てくるのは[ショップ名 :]という風にかっこがついているのにどうして?)

自分で答え出てますよ。

"]" は、"." に含まれているだけかと。

分からないこと2
/[注文者].*/で検索をして、なぜリターンが[注文情報が楽天市場のサーバに(以下略)]ということになるのか。
【注文者】で検索しているのになぜ【注文情報が】が抽出されるのかちんぷんかんぷんです…。

"[", "]" で囲んだ場合の意味を調べてみましたか?

image.png

まずは、[注文者] で何が抽出されるのか?を確認してみると分かるようになると思います

0Like

Comments

  1. @yuhtaryouko

    Questioner

    そういうことですね![]で囲まれた文字の1つでもマッチしたら抽出されるのですね。ありがとうございます。2つとも理解できました!

分からないこと 1 について答えます.

const reg_shop_name = new RegExp(/ショップ名 :(.*\r)/);
const shop_name = mail_body.match(reg_shop_name);

という部分について,JavaScript の開発者向けドキュメンテーションによれば

返値

Array を返します。これはグローバル (g) フラグの有無によって内容が変わります。
(略)
g フラグがなかった場合、最初に完全に一致したものと、それに関するキャプチャグループを返します。(略)

となっています.GAS は JavaScript を基にしているので,おそらく同じように動作します.つまり,

  • 検索結果として配列が返る.
  • その配列の最初の要素(shop_name[0])は,/ショップ名 :(.*\r)/ に最初にマッチした部分全体となる.つまり「ショップ名 :」から行末まで.
  • 配列の 2 番目の要素(shop_name[1])は,最初にマッチした部分のうちキャプチャグループ (.*\r) にマッチした部分となる.つまり「ショップ名 :」の直後から行末まで.

キャプチャグループにマッチした部分だけが必要ならば,「自分で試したこと」にある shop_name[1] で取り出すという方法で問題ないと思います.

0Like

Comments

  1. @yuhtaryouko

    Questioner

    返信ありがとうございます!【.*】に[]が含まれるという認識が抜けていました…
  2. ご理解いただけたようで何よりです.詳しく説明した甲斐がありました.

Your answer might help someone💌