使用正则表达式在逗号分隔的列表中去除重复项?

5
我将尝试使用正则表达式来过滤掉逗号分隔的字符串中的重复内容。我想在JavaScript中完成这个任务,但是我卡在如何使用反向引用上了。
例如:
1,1,1,2,2,3,3,3,3,4,4,4,5

Becomes:

1,2,3,4,5

或者:

a,b,b,said,said, t, u, ugly, ugly

变成

a,b,said,t,u,ugly
5个回答

7
为什么要使用正则表达式,而不是在 JavaScript 代码中实现呢?以下是示例代码(虽然有点混乱):
var input = 'a,b,b,said,said, t, u, ugly, ugly';
var splitted = input.split(',');
var collector = {};
for (i = 0; i < splitted.length; i++) {
   key = splitted[i].replace(/^\s*/, "").replace(/\s*$/, "");
   collector[key] = true;
}
var out = [];
for (var key in collector) {
   out.push(key);
}
var output = out.join(','); // output will be 'a,b,said,t,u,ugly'

p/s:在for循环中的那个正则表达式是用来修剪令牌而不是使它们唯一的。


1
+1 这样做的另一个好处是即使重复项不是连续的,也能将其删除。如果使用正则表达式来完成这个任务,那么这将是极其困难甚至不可能的。 - Jeremy Wall
正则表达式通常更加优雅,可以轻松解决问题。哪个更好 - 十几行代码还是十几个字符的正则表达式? - Anon.
我建议你在for...in循环中检查collector.hasOwnProperty(key)是否存在,因为如果有人扩展了Object.prototype,这将破坏你的代码。 - Christian C. Salvadó
匿名者,说得好,但处理CSV不是其中之一。此外,在编程中,优雅性非常主观。 - Ash
这并没有回答问题。那个人并没有要求 JavaScript 的解决方案。 - Display name

1
如果您坚持使用正则表达式,这里有一个Javascript的例子:
"1,1,1,2,2,3,3,3,3,4,4,4,5".replace (
    /(^|,)([^,]+)(?:,\2)+(,|$)/ig, 
    function ($0, $1, $2, $3) 
    { 
        return $1 + $2 + $3; 
    }
);

为了处理空格的修剪,稍作修改:

"1,1,1,2,2,3,3,3,3,4,4,4,5".replace (
    /(^|,)\s*([^,]+)\s*(?:,\s*\2)+\s*(,|$)\s*/ig, 
    function ($0, $1, $2, $3) 
    { 
        return $1 + $2 + $3; 
    }
);

话虽如此,似乎最好通过split进行标记化并处理重复项。


0

这是一个例子:

s/,([^,]+),\1/,$1/g;

这是关于 Perl 正则表达式替换的内容,但任何了解语法的人都可以将其转换为 JS 风格。


请注意,这在字符串开头附近的工作不是很正确 - 我可以修复它,但那会掩盖正则表达式核心本身的工作方式。这是一件坏事,因为最终会鼓励人们进行复制粘贴而不理解。 - Anon.
那么你应该通过解释来帮助人们理解。 - Billy Moon

0

我不使用正则表达式来处理这个问题。

我使用的函数接受一个包含逗号分隔值的字符串,并返回一个唯一值数组,无论它们在原始字符串中的位置如何。

注意:如果您传递包含引号值的CSV字符串,则Split将不会对引号值内的逗号进行任何不同处理。因此,如果您想处理真实的CSV,则最好使用第三方CSV解析器。

function GetUniqueItems(s)
{
    var items=s.split(",");

    var uniqueItems={};

    for (var i=0;i<items.length;i++)
    {           
        var key=items[i];
        var val=items[i];
        uniqueItems[key]=val;
    }

    var result=[];

    for(key in uniqueItems)
    {
        // Assign to output result field using hasOwnProperty so we only get 
        // relevant items
        if(uniqueItems.hasOwnProperty(key))
        {
            result[result.length]=uniqueItems[key];
        }
    }    
    return result;
}

0

使用JavaScript正则表达式

x="1,1,1,2,2,3,3,3,3,4,4,4,5"

while(/(\d),\1/.test(x))
    x=x.replace(/(\d),\1/g,"$1")

1,2,3,4,5


x="a,b,b,said,said, t, u, ugly, ugly"

while(/\s*([^,]+),\s*\1(?=,|$)/.test(x))
    x=x.replace(/\s*([^,]+),\s*\1(?=,|$)/g,"$1")

a,b,said, t, u,ugly

测试不充分,请告知是否有任何问题。


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