多重正则表达式替换

24

我被正则表达式搞糊涂了。当涉及到这些可怕的代码时,我认为我是有阅读障碍的。总之,一定有更简单的方法来完成这个任务(即在一行中列出一组替换实例)。有人知道吗?提前谢谢。

function clean(string) {
    string = string.replace(/\@~rb~@/g, '').replace(/}/g, '@~rb~@');
    string = string.replace(/\@~lb~@/g, '').replace(/{/g, '@~lb~@');
    string = string.replace(/\@~qu~@/g, '').replace(/\"/g, '@~qu~@');
    string = string.replace(/\@~cn~@/g, '').replace(/\:/g, '@~cn~@');
    string = string.replace(/\@-cm-@/g, '').replace(/\,/g, '@-cm-@');
    return string;
}

请提供一些样例输入,好吗? - Shekhar
1
你实际上想要做什么? - Gumbo
5个回答

43

您可以使用函数替换。对于每个匹配项,该函数决定应该用什么替换它。

function clean(string) {
    // All your regexps combined into one:
    var re = /@(~lb~|~rb~|~qu~|~cn~|-cm-)@|([{}":,])/g;

    return string.replace(re, function(match,tag,char) {
        // The arguments are:
        // 1: The whole match (string)
        // 2..n+1: The captures (string or undefined)
        // n+2: Starting position of match (0 = start)
        // n+3: The subject string.
        // (n = number of capture groups)

        if (tag !== undefined) {
            // We matched a tag. Replace with an empty string
            return "";
        }

        // Otherwise we matched a char. Replace with corresponding tag.
        switch (char) {
            case '{': return "@~lb~@";
            case '}': return "@~rb~@";
            case '"': return "@~qu~@";
            case ':': return "@~cn~@";
            case ',': return "@-cm-@";
        }
    });
}

23

你可以定义一个通用函数,如果您可以在代码的更多部分中重用它,这将是有意义的,并使其DRY。 如果您没有理由定义通用函数,则只需压缩清除序列的部分并保留其他替换。

function clean(string) {
    string = string.replace(/\@~rb~@|\@~lb~@|\@~qu~@|\@~cn~@|\@-cm-@/g, '')
      .replace(/}/g, '@~rb~@').replace(/{/g, '@~lb~@')
      .replace(/\"/g, '@~qu~@').replace(/\:/g, '@~cn~@')
      .replace(/\,/g, '@-cm-@');
    return string;
}

但是要小心,这段代码中替换的顺序已经改变...尽管看起来它们似乎不会影响结果。


1
你可以这样做:
function clean(str) {
    var expressions = {
        '@~rb~@': '',
        '}':      '@~rb~@',
        // ...
    };

    for (var key in expressions) {
        if (expressions.hasOwnProperty(key)) {
            str = str.replace(new RegExp(key, 'g'), expressions[key]);
        }
    }

    return str;
}

请记住,对象属性的顺序不可靠地确定(但大多数实现将按定义顺序返回它们)。如果您需要确保特定顺序,则可能需要使用多个类似这样的结构。

0
“一定有更简单的方法来做这件事 -(例如,在一行中列出一组替换实例)...”
“嗯,API优先思想。怎么样?”
var clean = multiReplacer({
    "@~rb~@": "",
    "@~lb~@": "",
    "@~qu~@": "",
    "@~cn~@": "",
    "@-cm-@": "",
    "}": "@~rb~@",
    "{": "@~lb~@",
    "\\": "@~qu~@",
    ":": "@~cn~@",
    ",": "@-cm-@"
});

管道:

// From http://simonwillison.net/2006/Jan/20/escape/
RegExp.escape = function(text)
{
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};

function multiReplacer(replacements)
{
    var regExpParts = [];
    for (prop in replacements)
    {
        if (replacements.hasOwnProperty(prop))
        {
            regExpParts.push(RegExp.escape(prop));
        }
    }

    var regExp = new RegExp(regExpParts.join("|"), 'g');
    var replacer = function(match)
    {
        return replacements[match];
    };

    return function(text)
    {
        return text.replace(regExp, replacer);
    };
}

-2

你可以按顺序将它们全部链接在一起。

function clean(string) {
    return string.replace(/\@~rb~@/g, '').replace(/}/g, '@~rb~@')
                 .replace(/\@~lb~@/g, '').replace(/{/g, '@~lb~@')
                 .replace(/\@~qu~@/g, '').replace(/\"/g, '@~qu~@')
                 .replace(/\@~cn~@/g, '').replace(/\:/g, '@~cn~@')
                 .replace(/\@-cm-@/g, '').replace(/\,/g, '@-cm-@');
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接