3

我在正则表达式方面很糟糕,所以我会以试图更好地描述我的问题的名义有点不合常规地传达我的问题。

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 不支持前瞻/后瞻,或者如果您愿意,'?>!'、'?<=')

4

2 回答 2

2

JavaScript 确实支持前瞻。而且由于您只需要向后看(也不需要向前看),因此有一种解决方法(这并不能真正帮助您的代码的可读性,但它确实有效!)。所以你可以做的是反转字符串和模式。

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修饰符)。

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

于 2012-12-08T01:05:01.067 回答
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>​

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

于 2012-12-08T03:30:36.437 回答