4

以下のコードをデバッグ モードで実行すると、画像に見られるように、for ループの最初の反復で期待値が取得されますが、2 番目の反復では null が取得されます。

最初の反復: ここに画像の説明を入力

2 回目の繰り返し: ここに画像の説明を入力

私は何を間違っていますか?

私が使用しているコードは次のとおりです。

var newer_than = ' newer_than:2d'; //added for faster debugging
var subjectIdentifier = '"Ingress Portal Submitted: "';
var searchString = 'subject:'+subjectIdentifier+newer_than;

function getPortalName(string) {
  var myRegexp = /: (.+)/g;
  var match = myRegexp.exec(string);
  var portalName = match[1];
  return portalName;
}

function getPortalsSubmitted() {
  var threads = GmailApp.search(searchString);
  for (i=0; i<threads.length; i++) {
    var subject = threads[i].getFirstMessageSubject();

    var portalName = getPortalName(subject);
    var subDate = threads[i].getMessages()[0].getDate();

    Logger.log([portalName,subDate]);
  }
}

function updatePortals() {
  var threads = GmailApp.search('subject:"Ingress Portal"');
  for (i=0; i<threads.length; i++) {
    Logger.log(threads[i].getFirstMessageSubject());
  }
}
4

1 に答える 1

12

この質問はコメントですでに回答されていますが、適切な回答をします。

この問題を理解するための重要な問題の 1 つはexec、正規表現にgフラグがある場合の動作です。順番に呼び出されると、別の文字列を渡したとしても、「次の」一致を検索しようとします。MDNのドキュメント リンクは次のとおりです。

また、MDN は、プロパティをリセットする可能性があるため、RegExp オブジェクト (リテラルであっても) を再作成しないように注意する必要があると述べていlastIndexます。少なくとも Apps Script ではそうではありません。正規表現リテラルがコード内のまったく同じ場所で何度も使用されている場合、Apps Script は正規表現をキャッシュし、同じオブジェクトを再利用します。

この 2 つの効果が組み合わさると、コードでこの「次の一致」動作を無意識のうちにトリガーしていることになります。

最も簡単な解決策は、フラグを削除するgことです。とにかくフラグは必要ないためです (最初の結果しか得られません)。var myRegexp = /: (.+)/g;ただし、行をに置き換えて、var myRegexp = new RegExp(': (.+)','g');Apps Script に新しいオブジェクトを強制的に与えることで、これを修正することもできます。

ここから学べる良い教訓は、必要のないフラグは使用しないことです。怠け者で、「念のため」と考えずにフラグを立ててしまうことがあります。

于 2013-06-08T04:12:51.580 に答える