如何调整while循环中的variables作用域以匹配CoffeeScript中的所有正则expression式?

我在coffeescript循环中遇到了一些麻烦。

原来的function如下, 来源是这个答案 :

// 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 …'循环被忽略了吗? 以及如何在coffeescript中的特定范围声明一个variables? 而我几乎没有想法在这里…任何其他匹配所有的正则expression式除了这个while循环(顺便说一句,我已经尝试过\gm标志,它仍然只打一场比赛)? 或者有没有一种方法可以在咖啡脚本中获得这个范围?

整个Coffee Script代码是:

 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, " ")); 

实际的问题不是你认为的。 实际的问题是==编译为=== 。 这是你如何解决它:

 # 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是一个string,代表一个整数。 你可以尝试在JavaScript上的几个值,并看到它的作品。 parseInt(i)是一个数字,而i是一个string。 在JavaScript中,如果您在string和数字上使用== ,则它将隐含地强制,并且testing将按您所期望的那样工作。 这种隐式强制通常是意想不到的,所以CoffeeScript通过没有==运算符的等价物而将其阻止,将== (和)转换成=== ,它首先比较types。 在这种情况下,数字和string将永远不会相等,所以if的条件永远不会被满足,所以什么都不会被推到数组上。