Javascript的正则表达式背后的解决方法?

时间:2012-12-08 00:45:11

标签: javascript regex

我在正则表达式上很糟糕所以我会以试图更好地描述我的问题的名义来传达我的问题。

var TheBadPattern = /(\d{2}:\d{2}:\d{2},\d{3})/;
var TheGoodPattern = /([a-zA-Z0-9\-,.;:'"])(?:\r\n?|\n)([a-zA-Z0-9\-])/gi;

// My goal is to then do this
inputString = inputString.replace(TheGoodPattern, '$1 $2);

问题:我希望匹配所有好的模式并进行后续的查找/替换,除非它们是由坏模式进行的,任何想法如何?我能够用支持lookbehind的其他语言来完成这个,但是如果没有它我会感到茫然吗? (ps:根据我的理解,JS不支持前瞻/后视或者如果你愿意,'?>!','?< =')

2 个答案:

答案 0 :(得分:2)

JavaScript确实支持前瞻。而且由于你只需要一个lookbehind(也不是一个前瞻),有一个解决方法(它不会真正帮助你的代码的可读性,但它的工作原理!)。所以你可以做的是反转字符串和模式。

inputString = inputString.split("").reverse().join("");
var pattern = /([a-z0-9\-])(?:\n\r?|\r)([a-z0-9\-,.;:'"])(?!\d{3},\d{2}:\d{2}:\d{2})/gi
inputString = inputString.replace(TheGoodPattern, '$1 $2');
inputString = inputString.split("").reverse().join("");

请注意,您已冗余使用大写字母(它们正在处理i修饰符)。

如果您提供了一些示例输入,我实际上会为您测试。

答案 1 :(得分:1)

我还使用了m.buettner推荐的反向方法,根据您的模式,它可能会非常棘手。我发现如果你匹配简单的模式或字符串,那么解决方法很有效。

有了这个说我以为我会在盒子外面走一点只是为了好玩。这个解决方案并非没有自己的缺点,但它也有效,并且应该很容易适应具有中到复杂正则表达式的现有代码。

http://jsfiddle.net/52QBx/

JS:

function negativeLookBehind(lookBehindRegExp, matchRegExp, modifiers)
{
    var text = $('#content').html();
    var badGoodRegex = regexMerge(lookBehindRegExp, matchRegExp, modifiers);
    var badGoodMatches = text.match(badGoodRegex);
    var placeHolderMap = {};
    for(var i = 0;i<badGoodMatches.length;i++)
    {
        var match = badGoodMatches[i];
        var placeHolder = "${item"+i+"}"
        placeHolderMap[placeHolder] = match;
        $('#content').html($('#content').html().replace(match, placeHolder));
    }

    var text = $('#content').html();
    var goodRegex = matchRegExp;
    var goodMatches = text.match(goodRegex);

    for(prop in placeHolderMap)
    {
        $('#content').html($('#content').html().replace(prop, placeHolderMap[prop]));
    }
    return goodMatches;
}
function regexMerge(regex1, regex2, modifiers)
{
    /*this whole concept could be its own beast, so I just asked to have modifiers for the combined expression passed in rather than determined from the two regexes passed in.*/
    return new RegExp(regex1.source + regex2.source, modifiers);
}
var result = negativeLookBehind(/(bad )/gi, /(good\d)/gi, "gi");
alert(result);

HTML:

<div id="content">Some random text trying to find good1 text but only when that good2 text is not preceded by bad text so bad good3 should not be found bad good4 is a bad oxymoron anyway.</div>​

主要思想是找到所有的总模式(包括lookbehind和real match),并暂时从正在搜索的文本中删除它们。我使用了地图,因为隐藏的值可能会有所不同,因此每次替换都必须是可逆的。然后我们可以只运行你想要找到的项目的正则表达式,而没有那些与后面的方式相匹配的项目。确定结果后,我们将换回原始项目并返回结果。这是一个古怪而又实用的解决方法。