質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

2回答

567閲覧

文字列に対して抽出を繰り返えし正規表現に直したい

teratailuser123

総合スコア16

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

1クリップ

投稿2020/09/07 09:21

下記のようなメールを必要箇所抽出し、正規表現に直そうと思っているのですが、抽出方法がわからず困っております。
抽出したい内容としては『[]』中の商品型番と商品型番以降から次の商品型番の一つ前の行を削除したご注文内容の詳細、それに対して注文個数に応じて記入を繰り返すといったものです。

自分では注文されたものが1つだった場合しか思いつかず別商品を注文されたときの処理の方法が思い浮かびません。
引き続き方法を考えますが、当方プログラミングは初めて日が浅く、知らない関数などもあるため解決策が見出せずにいます。ある程度規則性のある処理内容と思っていますためプログラムで動かせるものとは思います。
何卒お力をお貸しください。

自分の思い浮かぶ限りの解決方法

文字列内の『[』の文字の数を数え1つだった場合と複数だった場合で処理を分ける

1つだった場合『[]』の間の文字を取得し商品型番を取り var code とする
___________↓
___________『]』から『=』までの文字を取得し var details とする
___________↓
___________『円 』から『個』までの文字をとり個数に合わせて var code と var detailsを繰り返す
___________↓
___________メールタイトルを var code とする


複数だった場合『[』から同一行に存在しない『[』までを取る 仮に var a とする

何らかの方法で var a の下から2行を削除し a.replase("]", "") する var aaとする

文字列内において var a の一つ上の行から個数を取得し、個数に合わせてvar a を繰り返す

var aaの1行目を取得し商品型番をとる var code1とする

上記を『==』が来るまで繰り返す

メール 内容

ーーーーーーーーーーーーー
商品名A 10,000円 1個 10,000円
[商品型番A]
色:黒
サイズ:22.5
素材:エナメル
オプション:ーー

商品名B 5,000円 2個 5,000円
[商品型番B]
色:黒
サイズ:22
素材:革
=============

正規表現後

メールタイトル:商品型番A・商品型番B・商品型番B

商品型番A
色:黒
サイズ:22.5
素材:エナメル
オプション:ーー

商品型番B
色:黒
サイズ:22
素材:革

商品型番B
色:黒
サイズ:22
素材:革

現在書けている分のコード

GoogleAppsScript

1function myFunction() { 2 var text = (function() {/* 3ーーーーーーーーーーーーー 4商品名A 10,000円 1個 10,000円 5[商品型番A] 6色:黒 7サイズ:22.5 8素材:エナメル 9オプション:ーー 10 11商品名B 5,000円 2個 5,000円 12[商品型番B] 13色:黒 14サイズ:22 15素材:革 16============= 17*/}).toString().match(//*\n*([^]*)*//)[1]; 18 19 20var count = (text.match(/[/g) || []).length; 21console.log(count); 22 23 24 if(count = 1){ 25 const result = text.match(/[(.*)]/); 26  if (result != null) { 27 var code =result[1] 28} 29 30 var details = new RegExp(']'+'[\s\S]*?'+'='); 31 var Details = text.match(details)[0].replace(']', '').replace('=', ''); 32 33 34 35} 36

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2020/09/07 09:53

そもそもが分かりませんが、「正規表現に直そう」は文字通りの意味(処理結果として正規表現が出力される)ですか?それとも「正規表現で直そう」(正規表現を使って書き直す)の書き間違いですか?
teratailuser123

2020/09/07 11:08

otn様 ご質問いただきありがとうございます。 処理結果として正規表現が出力されることを目指しております。
otn

2020/09/07 12:56

どんな正規表現を出力したいのでしょうか?
guest

回答2

0

ベストアンサー

ひとつの商品分にマッチする正規表現を使う例。
書きやすさからmatchAllを使ったのでIEでは動作しない。

regex

1/^.*? +[\d,]++(?<count>[\d,]+)+[\d,]+\n[(?<model>.*?)]\n(?<content>(?:.*?\n)+?)(?=^.*?\n[|+)/mg

Javascript

1text = `ーーーーーーーーーーーーー 2商品名A 10,000円 1個 10,000円 3[商品型番A] 4色:黒 5サイズ:22.5 6素材:エナメル 7オプション:ーー 8 9商品名B 5,000円 2個 5,000円 10[商品型番B] 11色:黒 12サイズ:22 13素材:革 14============= 15` 16 17var results = text.matchAll(/^.*? +[\d,]++(?<count>[\d,]+)+[\d,]+円\n[(?<model>.*?)]\n(?<content>(?:.*?\n)+?)(?=^.*?\n[|+)/mg); 18 19var mailTitle = ""; 20var mailBody = "\n"; 21for (const result of results) { 22 mailTitle += (result.groups.model + "・").repeat(result.groups.count); 23 var modelAndContent = result.groups.model + '\n' + result.groups.content; 24 if (modelAndContent.slice(-2) !== '\n\n') { 25 modelAndContent += '\n'; 26 } 27 mailBody += modelAndContent.repeat(result.groups.count) 28} 29if (mailTitle.length > 1) { 30 mailTitle = mailTitle.slice(0, -1); 31} 32 33console.log("メールタイトル: " + mailTitle) 34console.log(mailBody)

result

1メールタイトル: 商品型番A・商品型番B・商品型番B 2 3商品型番A 4色:黒 5サイズ:22.5 6素材:エナメル 7オプション:ーー 8 9商品型番B 10色:黒 11サイズ:22 12素材:革 13 14商品型番B 15色:黒 16サイズ:22 17素材:革 18

投稿2020/09/07 15:41

編集2020/09/07 15:42
Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teratailuser123

2020/09/08 07:43

Daregada様 回答ありがとうございます! 書いていただいたコードで希望の動作ができました。 勉強中の身のためわからない点などがたくさんありましたが、しっかり勉強し自分で書けるように精進してまいります! また、https://teratail.com/questions/290445?modal=q-comp こちらで今回の質問に関連する質問をさせていただきました。 もしよろしければこちらも回答いただけましたら幸いです。
guest

0

ざっと見る限り、正規表現は使うとしても補助的なところでしょう。方針の基本的なところを考え直す必要があるように見えます。

処理はメール全体を一度に処理するのではなく、行単位で進めるのが良さそうです。

具体的には、一行分データを読み取っては次のルールに沿って処理していきます。

  • 読んだ行が[なんちゃら]であった場合は「商品情報取り出しモード」に入る。
  • 読んだ行が空行であった場合は、蓄積した情報を出力して、「商品情報取り出しモード」から出る。
  • 「商品情報取り出しモード」にあるうちは必要な情報を溜め込んでいく。正規表現を使うとすればここ。参考:https://tonari-it.com/gas-regular-expression/#toc2

正規表現を覚え始めると何でも正規表現一発でやってみたくなるものですが、substrとかsliceとかで処理した方が遥かに楽に成果が出せることが少なくないので、そのように出来ることはないかよく考えてみることをお勧めします。

投稿2020/09/07 13:21

KojiDoi

総合スコア13669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問