1

coffeescript の while ループに少し問題があります。

元の関数は次のとおりで、ソースはこの回答です。

// Return all pattern matches with captured groups
RegExp.prototype.execAll = function(string) {
    var match = null;
    var matches = new Array();
    while (match = this.exec(string)) {
        var matchArray = [];
        for (i in match) {
            if (parseInt(i) == i) {
                matchArray.push(match[i]);
            }
        }
        matches.push(matchArray);
    }
    return matches;
}

意図したとおりに機能します。私はjs2coffeeを介して変換しました。コーヒースクリプトは次のとおりです。

# Return all pattern matches with captured groups
RegExp::execAll = (string) ->

  matches = new Array()
  match = null
  while match = @exec(string) 
    matchArray = new Array()
    for i of match
      matchArray.push match[i]  if parseInt(i) is i
    matches.push matchArray
  matches

次のようにコンパイルされます。

RegExp.prototype.execAll = function(string) {
  var i, match, matchArray, matches;
  matches = new Array();
  match = null;
  while (match = this.exec(string)) {
    matchArray = new Array();
    for (i in match) {
      if (parseInt(i) === i) {
        matchArray.push(match[i]);
      }
    }
    matches.push(matchArray);
  }
  return matches;
};

結果は次のとおりです。

[
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  []
]

私が見ることができる唯一の違いは次の行であるため、変数のスコープのためにこれは機能しないと思います:

RegExp.prototype.execAll = function(string) {
  var i, match, matchArray, matches;

対オリジナル:

RegExp.prototype.execAll = function(string) {
    var match = null;
    var matches = new Array();
    while (match = this.exec(string)) {
        var matchArray = [];

matchArrayスコープ アウトの方法に注意してください... これを回避する方法を見つけることができませんでしたが、調査中に次の質問が見つかりました。コーヒースクリプトの特定のスコープで変数を宣言するにはどうすればよいですか? そして、私はここでほとんどアイデアがありません...このwhileループ以外のすべてを正規表現と一致させる他の方法はありますか(ちなみに、\gmフラグを試してみましたが、まだ1つの一致しかヒットしません)? または、コーヒースクリプトでこのスコープを正しく取得する方法はありますか?

全体のコーヒー スクリプト コードは次のとおりです。

fs = require 'fs'

text = fs.readFileSync('test.md','utf8')

#console.log text

regex = /^(?:@@)(\w+):(.*.)/gm
# Return all pattern matches with captured groups
RegExp::execAll = (string) ->

  matches = new Array()
  match = null
  while match = @exec(string) 
    matchArray = new Array()
    for i of match
      matchArray.push match[i]  if parseInt(i) is i
    matches.push matchArray
  matches

res = regex.execAll text
#console.log regex.exec text
console.log (JSON.stringify(res, null, "  ") )

そして、動作するJavascriptはこれです:

var fs, regex, res, text;

fs = require('fs');

text = fs.readFileSync('test.md', 'utf8');

regex = /^(?:@@)(\w+):(.*.)/gm;

// Return all pattern matches with captured groups
RegExp.prototype.execAll = function(string) {
    var match = null;
    var matches = new Array();
    while (match = this.exec(string)) {
        var matchArray = [];
        for (i in match) {
            if (parseInt(i) == i) {
                matchArray.push(match[i]);
            }
        }
        matches.push(matchArray);
    }
    return matches;
}

res = regex.execAll(text);

//console.log(regex.exec(text));

console.log(JSON.stringify(res, null, "  "));
4

1 に答える 1

7

実際の問題は、あなたが思っていることではありません。実際の問題は、==コンパイルされて===. 修正方法は次のとおりです。

# Return all pattern matches with captured groups
RegExp::execAll = (string) ->
  matches = []
  while match = @exec string
    matches.push(group for group in match)
  matches

しかし、なぜ===うまくいかないのか不思議に思うかもしれません。したがって、私はあなたに提示します:

===うまくいかない理由(この場合)

parseInt(i) == iiが整数を表す文字列かどうかを判断することになっていました。JavaScript でいくつかの値を試してみて、動作することを確認してください。parseInt(i)は数値ですiが、 は文字列です。JavaScript では==、文字列と数値を使用している場合、暗黙的に強制され、テストは期待どおりに機能します。この暗黙の型強制は予期しないことが多いため、CoffeeScript では、最初に型を比較す​​る(and ) を==に変換する演算子に相当するものを持たないことで、これが起こらないようにしています。その場合、数値と文字列が等しくなることはないため、の条件が満たされないため、配列には何もプッシュされません。==is===if

于 2012-12-29T05:25:25.390 に答える