感谢模板文字的奇妙世界,您现在可以在 ES6 中编写大的、多行的、注释良好的甚至语义嵌套的正则表达式。
//build regexes without worrying about
// - double-backslashing
// - adding whitespace for readability
// - adding in comments
let clean = (piece) => (piece
    .replace(/((^|\n)(?:[^\/\\]|\/[^*\/]|\\.)*?)\s*\/\*(?:[^*]|\*[^\/])*(\*\/|)/g, '$1')
    .replace(/((^|\n)(?:[^\/\\]|\/[^\/]|\\.)*?)\s*\/\/[^\n]*/g, '$1')
    .replace(/\n\s*/g, '')
);
window.regex = ({raw}, ...interpolations) => (
    new RegExp(interpolations.reduce(
        (regex, insert, index) => (regex + insert + clean(raw[index + 1])),
        clean(raw[0])
    ))
);
使用它,您现在可以像这样编写正则表达式:
let re = regex`I'm a special regex{3} //with a comment!`;
输出
/I'm a special regex{3}/
或者多线呢?
'123hello'
    .match(regex`
        //so this is a regex
        //here I am matching some numbers
        (\d+)
        //Oh! See how I didn't need to double backslash that \d?
        ([a-z]{1,3}) /*note to self, this is group #2*/
    `)
    [2]
输出hel,整洁!
“如果我需要实际搜索换行符怎么办?”,然后使用\n愚蠢的!
在我的 Firefox 和 Chrome 上工作。
好的,“来点更复杂的东西怎么样?” 
当然,这是我正在研究的对象解构 JS 解析器的一部分:
regex`^\s*
    (
        //closing the object
        (\})|
        //starting from open or comma you can...
        (?:[,{]\s*)(?:
            //have a rest operator
            (\.\.\.)
            |
            //have a property key
            (
                //a non-negative integer
                \b\d+\b
                |
                //any unencapsulated string of the following
                \b[A-Za-z$_][\w$]*\b
                |
                //a quoted string
                //this is #5!
                ("|')(?:
                    //that contains any non-escape, non-quote character
                    (?!\5|\\).
                    |
                    //or any escape sequence
                    (?:\\.)
                //finished by the quote
                )*\5
            )
            //after a property key, we can go inside
            \s*(:|)
      |
      \s*(?={)
        )
    )
    ((?:
        //after closing we expect either
        // - the parent's comma/close,
        // - or the end of the string
        \s*(?:[,}\]=]|$)
        |
        //after the rest operator we expect the close
        \s*\}
        |
        //after diving into a key we expect that object to open
        \s*[{[:]
        |
        //otherwise we saw only a key, we now expect a comma or close
        \s*[,}{]
    ).*)
$`
它输出 /^\s*((\})|(?:[,{]\s*)(?:(\.\.\.)|(\b\d+\b|\b[A-Za-z$_][\w$]*\b|("|')(?:(?!\5|\\).|(?:\\.))*\5)\s*(:|)|\s*(?={)))((?:\s*(?:[,}\]=]|$)|\s*\}|\s*[{[:]|\s*[,}{]).*)$/
并通过一个小演示运行它?
let input = '{why, hello, there, "you   huge \\"", 17, {big,smelly}}';
for (
    let parsed;
    parsed = input.match(r);
    input = parsed[parsed.length - 1]
) console.log(parsed[1]);
成功输出
{why
, hello
, there
, "you   huge \""
, 17
,
{big
,smelly
}
}
请注意成功捕获带引号的字符串。
我在 Chrome 和 Firefox 上测试过,效果很好!
如果好奇,你可以检出我在做什么,以及它的示范。
虽然它只适用于 Chrome,因为 Firefox 不支持反向引用或命名组。所以请注意,这个答案中给出的例子实际上是一个绝育版本,可能很容易被欺骗接受无效的字符串。