0

我正在尝试编写一个 JavaScript 函数,该函数使用正则表达式删除任何第二次出现的字符。这是我的功能

var removeSecondOccurrence = function(string) {
return string.replace(/(.*)\1/gi, '');
}

它只是删除连续出现的事件。我希望它甚至可以删除不连续的一个。例如,papirana 应该变成 pairn。

请帮忙

4

4 回答 4

4

非正则表达式解决方案:

 "papirana".split("").filter(function(x, n, self) { return self.indexOf(x) == n }).join("")

正则表达式代码很复杂,因为 JS 不支持lookbehinds:

str = "papirana";
re = /(.)(.*?)\1/;
while(str.match(re)) str = str.replace(re, "$1$2")

或第一种方法的变体:

"papirana".replace(/./g, function(a, n, str) { return str.indexOf(a) == n ? a : "" })
于 2013-08-15T17:47:02.990 回答
2

使用零宽度前瞻断言,您可以执行类似的操作

"papirana".replace(/(.)(?=.*\1)/g, "")

返回

"pirna"

字母当然是相同的,只是顺序不同。

传递字符串的反向并使用结果的反向,您可以获得所需的内容。

于 2013-08-15T17:51:06.460 回答
0

这就是你将如何使用循环:

var removeSecondOccurrence = function(string) {
    var results = "";
    for (var i = 0; i < string.length; i++)
        if (!results.contains(string.charAt(i)))
            results += string.charAt(i);
}

基本上:对于输入中的每个字符,如果您还没有看到该字符,请将其添加到结果中。至少清晰易读。

于 2013-08-15T17:49:55.350 回答
0

米歇尔说的。

事实上,我强烈怀疑它不能使用正则表达式来完成。或者更确切地说,如果你反转字符串,删除除第一次出现之外的所有字符串,然后再次反转,但这是一个肮脏的技巧,米歇尔建议的方法更好(并且可能更快)。

如果你仍然热衷于正则表达式......

"papirana".
    split("").
    reverse().
    join("").
    replace(/(.)(?=.*\1)/g, '').
    split("").
    reverse().
    join("")

// => "pairn"

如果没有所有翻页,除了第一次出现之外,您找不到所有内容的原因是双重的:

  • JavaScript 没有lookbehinds,只有lookaheads
  • 即使确实如此,我认为任何正则表达式风格都不允许可变长度的lookbehinds
于 2013-08-15T17:51:56.070 回答