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确定范围...我找不到解决方法,但是当我研究时我发现这些问题是 CoffeeScript 中遗漏了 `do...while` 循环...?以及如何在咖​​啡脚本的特定范围内声明变量?而且我在这里几乎没有想法......除了这个while循环之外,还有任何其他方式将所有与正则表达式匹配(顺便说一句,我已经尝试过\gm标志并且它仍然只匹配一个匹配)?或者有没有办法在咖啡脚本中获得这个范围?

整个咖啡脚本代码是:

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) == i应该确定是否i是表示整数的字符串。您可以在 JavaScript 中对几个值进行尝试,看看它是否有效。parseInt(i)是一个数字,而i是一个字符串。在 JavaScript 中,如果您在==字符串和数字上使用,它将隐式强制执行,并且测试将按您预期的那样工作。这种隐式强制转换通常是出乎意料的,因此 CoffeeScript 不允许它发生,因为它没有等效的==运算符,将==(and is) 转换为===首先比较类型的运算符。在这种情况下,数字和字符串永远不会相等,因此if永远不会满足 ' 条件,因此不会将任何内容推送到数组中。

于 2012-12-29T05:25:25.390 回答