1

我有以下正则表达式:

/(?:this\.(\w+)\(([\s\S]*?)\))/g

它用于获取这样的代码:

this.doSomething(foo, bar)

并将其替换为:

this.lookup('doSomething', [foo, bar])

对于该用例(这是最常见的),它可以正常工作,但如果在其中使用它就不起作用this

this.doSomething(foo, bar, this.baz())

结果错误地是这样的:

this.lookup('doSomething', [foo, bar, this.baz(]))

应该是这样的:

this.lookup('doSomething', [foo, bar, this.baz()])

嗯,这是第一个问题。它实际上应该像 一样转换this.doSomething,所以最终结果应该是:

this.lookup('doSomething', [foo, bar, this.lookup('baz', [])]);

基本上,我的正则表达式假设右括号 fromthis.baz()是右括号,this.doSomething()并且也不会递归操作。我在这里需要某种递归行为/控制。

我听说过xregexp,但我不确定这对我有什么帮助。似乎真正的语言解析器可能是唯一的出路。我在那里没有太多经验,但我不怕弄脏我的手。似乎像 Esprima 这样的工具可以提供帮助?

归根结底,我希望在代码的构建步骤中对语言/语法进行细微的更改,即与 Babel 完全一样。我实际上正在使用 Babel。也许某种 Babel 插件是一种选择?

无论如何,我对快速修复正则表达式技巧或更专业/强大的语言解析技术持开放态度。我也很好奇这些问题通常是如何处理的。扫描整个输入并匹配我假设的打开/关闭大括号/括号/等?

4

1 回答 1

2

这是一个如何使用 Babel 插件执行此操作的示例:

var names = ['doSomething', 'baz'];

module.exports = function(context){
    var t = context.types;

    return {
        visitor: {
            CallExpression: function(path){
                var callee = path.get('callee');
                // Only process "this.*()" calls.
                if (!callee.isMemberExpression() ||
                    !callee.get('object').isThisExpression() ||
                    !callee.get('property').isIdentifier()) return;

                // Make sure the call is to one of your specific functions.
                if (names.indexOf(path.node.callee.property.name) === -1) return;

                // Build "this.lookup('<name>', [])".
                path.replaceWith(t.callExpression(
                    t.memberExpression(t.thisExpression(), t.identifier('lookup')),
                    [
                        t.stringLiteral(path.node.callee.property.name),
                        t.arrayExpression(path.node.arguments),
                    ]
                ));
            }
        }
    };
}

例如,如果将其放入plugin.js函数中,则可以创建一个.babelrc配置文件并确保./plugin.js或指向它的任何路径都在您的plugins数组中,例如

.babelrc

{
  "presets": ['es2015'],
  "plugins": ['./plugin']
}
于 2015-12-05T19:32:53.233 回答