javascript 使用正则表达式删除评论

javascript delete comment by use regex

requirejs源码:

使用下面的代码删除评论

var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;

function commentReplace(match, multi, multiText, singlePrefix) {
    return singlePrefix || '';
}

// for example

var funcName = function(){
    /* comment */
    console.log('comment') // comment
    return 'delete comment'
}

funcName.toString().replace(commentRegExp,commentReplace);

我想知道 commentRegExp 是

的原因

/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;

而不是

/(\/\*([\s\S]*?)\*\/| \/\/(.*)$)/mg;

这样我们就可以使用

funcName.toString().replace(/(\/\*([\s\S]*?)\*\/| \/\/(.*)$)/mg,'')

而不是

funcName.toString().replace(commentRegExp,commentReplace);

谁能告诉我([^:]|^)/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg里面的作用

([^:]|^) 匹配行首或非冒号的字符 (:)。

这是为了防止匹配像

这样的网址
var a = "http://url.com";

([^:]|^) 还捕获匹配的文本,以便使用反向引用 </code> 作为替换,将那个字符放回原处。</p> <hr> <p>请注意,此表达式也将匹配某些不是注释的情况,例如中间引号。</p> <pre><code>var b = "this is //not a comment matched";


你应该use a JavaScript parser instead.

commentRegExp 不是用于剥离注释的通用正则表达式。

如果您希望删除一般的注释,您应该按照 所说的进行操作,并使用 JavaScript 解析器。

为什么 RequireJS 使用这个表达式?

要理解正则表达式为什么是这个样子,就需要理解它的用途。它仅用于 require.js 中的 one place:

callback
    .toString()
    .replace(commentRegExp, commentReplace)
    .replace(cjsRequireRegExp, function (match, dep) {
        deps.push(dep);
    });

callback 是传递给 define 调用的回调。例如,此调用的单个参数在上面的代码中为 callback

define(function (require) {});

我引用的 RequireJS 代码的唯一目标是为导入模块的 CommonJS 风格提供支持。它遍历回调源并查找所有require 调用的实例具有一个字符串文字参数。如果您有以 CommonJS 形式编写的代码:

var foo = require("foo");
var bar = require("bar");
// Do stuff with foo and bar.

exports.q = "something";

你可以把它包裹在 define:

define(function (require, exports, module) {
  var foo = require("foo");
  var bar = require("bar");
  // Do stuff with foo and bar.

  exports.q = "something";
});

尽管 require 调用 看起来 就像它们是同步加载模块一样,但 RequireJS 总是异步加载模块,所以为了让 require 调用工作,RequireJS 执行一个计算,使上面的内容等同于以下内容:

define(["require", "exports", "module", "foo", "bar"], function (require, exports, module) {
  var foo = require("foo");
  var bar = require("bar");
  // Do stuff with foo and bar.

  exports.q = "something";
});

回调之前出现的数组是define定义的模块的依赖项列表。模块 requireexportsmodule 是特殊模块,它们始终被定义并提供要传递给使用 CommonJS 语法的回调的值。然后将 require 调用中出现的模块添加到依赖项列表中。这意味着所有出现在 require 回调中的调用传递给 define 的所有模块都在回调运行 之前 加载。因此,当 var foo = require("foo") 执行时,RequireJS 不会加载模块,而只是从其模块缓存中获取它。

您正在查看的正则表达式仅用于执行我刚才描述的计算。它允许 RequireJS 检测并正确处理这些情况:

require("foo" /* something */);
require(// Something
        "foo");

已经指出,虽然 commentRegExp 有一条规定不避免将 '//:' 作为注释,但它会破坏像这样的东西:

var b = "this is //not a comment matched";

该使用的目的,无所谓。在 commentRegExp 之后使用的 cjsRequireRegExp 表达式是 only 寻找 require 调用。因此,即使发生上述情况,也没有任何后果,因为 cjsRequireRegExp 不会匹配它。它与 :// 不匹配的原因是这样的:

require("http://foo.com/something")

下面的呢?

require("lib//something")

正则表达式将从'//' 删除到行尾,正确。 但是,'//' 等同于 '/' 所以只需将模块名称设为 lib/something.

RequireJS 使用正则表达式而不是 JavaScript 解析器,因为:a) 它会大大减慢模块加载速度,并且 b) 在 require.js 中包含这样的解析器会使它比目前。