如何在while循环中调整变量范围以匹配CoffeeScript中的所有正则表达式?

Log*_*gan 1 javascript regex scope node.js coffeescript

我在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;
}
Run Code Online (Sandbox Code Playgroud)

它按预期工作.我通过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
Run Code Online (Sandbox Code Playgroud)

编译为:

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;
};
Run Code Online (Sandbox Code Playgroud)

结果是:

[
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  []
]
Run Code Online (Sandbox Code Playgroud)

我认为这不起作用,因为可变范围,因为我能看到的唯一区别是这一行:

RegExp.prototype.execAll = function(string) {
  var i, match, matchArray, matches;
Run Code Online (Sandbox Code Playgroud)

与原作:

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

请注意如何确定matchArray范围...我无法找到解决方法,但在我研究的过程中,我发现这些问题是"从咖啡脚中留下来的......而``循环......"?如何在CoffeeScript中特定的范围声明一个变量?而且我在这里几乎没有想法...除了这个循环之外还有任何其他匹配regexp的方法(顺便说一句,我尝试过\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, "  ") )
Run Code Online (Sandbox Code Playgroud)

和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, "  "));
Run Code Online (Sandbox Code Playgroud)

ick*_*fay 7

实际问题不是你想象的那样.实际的问题是==编译到===.以下是您修复它的方法:

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

但你可能想知道为什么===不起作用.因此,我向您呈现:

为什么===不起作用(在这种情况下)

parseInt(i) == i应该确定if是否i是表示整数的字符串.您可以在JavaScript中尝试使用一些值,看看它是否有效.parseInt(i)是一个数字,而是i一个字符串.在JavaScript中,如果您使用==字符串和数字,它将隐式强制,测试将按预期工作.这种隐式强制通常是意料之外的,因此CoffeeScript不允许它通过没有等效的==运算符,将==(和is)转换为===首先比较类型而发生.在这种情况下,数字和字符串将永远不会相等,因此if永远不会满足条件,因此不会将任何内容推送到数组上.