如何在javascript中从字符串中获取唯一字符列表?

如何在javascript中从字符串中获取唯一字符列表?,javascript,regex,duplicate-removal,Javascript,Regex,Duplicate Removal,我有一些文本文件,每个文件都混合了西文和中文字符。我想要每个文件中出现的汉字列表 我试过了 ch = text.match(/[\u4E00-\u9FFF]/g); // unicode usual chinese characters - that'll do for me if (ch != null) { alert(ch); } 这给了我一个汉字列表,但有一些重复。例如: 肉,捕,兵,死,兵,半,水 肉捕兵死半水 存档 卵,水,半,水,土,木,水,清,慢,底,海,海,海,清

我有一些文本文件,每个文件都混合了西文和中文字符。我想要每个文件中出现的汉字列表

我试过了

ch = text.match(/[\u4E00-\u9FFF]/g); // unicode usual chinese characters - that'll do for me
if (ch != null) {
    alert(ch);
}
这给了我一个汉字列表,但有一些重复。例如:

肉,捕,兵,死,兵,半,水
肉捕兵死半水
存档

卵,水,半,水,土,木,水,清,慢,底,海,海,海,清,清,清,木,清,慢,底,清,土,半,水,水,土,半,水,土
另一方面

1) 我不需要那些逗号。他们来自哪里?(我可以用一次替换就把它们去掉,但是因为我使用的是正则表达式,我认为如果我在正则表达式内部解决它,速度可能会更快。)

2) 如何仅获取唯一值?例如:

肉,捕,兵,死,兵,半,水
肉捕兵死半水
对于第一个文件

卵水半土木清慢底海

对于第二个…

逗号来自默认数组到字符串的转换。使用
ch.join(“”)
将数组转换为字符串

要删除重复值,请使用此行:

ch = text.match(/([\u4E00-\u9FFF])/g);
ch = ch.filter(function (c, i) { return ch.indexOf(c) === i; }).join('');

逗号来自默认数组到字符串的转换。使用
ch.join(“”)
将数组转换为字符串

要删除重复值,请使用此行:

ch = text.match(/([\u4E00-\u9FFF])/g);
ch = ch.filter(function (c, i) { return ch.indexOf(c) === i; }).join('');
Array.prototype.getUnique=function(){
变量u={},a=[];
对于(变量i=0,l=this.length;i
Array.prototype.getUnique=function(){
变量u={},a=[];
对于(变量i=0,l=this.length;i
试试这个:

var text    =   "卵水半水土木水清慢底海海海清清清木清慢底清土半水水土半水土",


    re      =   /([\u4E00-\u9FFF])/g,
    unique  =   {},
    chars   =   "", c;

while(c = re.exec(text)){
    if(!unique[c[0]]){
        chars += c[0];
        unique[c[0]] = true;
    }
}
chars.split("");
它返回:

["卵", "水", "半", "土", "木", "清", "慢", "底", "海"]
是的,当浏览器将数组类型转换为字符串时,您看到的逗号是:它将每个值的字符串表示形式与逗号连接在一起。我猜这是源于您原始示例中对“alert”的调用,它提供了一个数组(从字符串的“Match”方法返回)

Array的“filter”方法在传统浏览器中不受支持,但它很容易进行多填充(如果您只关心像IE9这样的最新支持代理,当然不需要进行多填充)。

尝试以下方法:

var text    =   "卵水半水土木水清慢底海海海清清清木清慢底清土半水水土半水土",


    re      =   /([\u4E00-\u9FFF])/g,
    unique  =   {},
    chars   =   "", c;

while(c = re.exec(text)){
    if(!unique[c[0]]){
        chars += c[0];
        unique[c[0]] = true;
    }
}
chars.split("");
它返回:

["卵", "水", "半", "土", "木", "清", "慢", "底", "海"]
是的,当浏览器将数组类型转换为字符串时,您看到的逗号是:它将每个值的字符串表示形式与逗号连接在一起。我猜这是源于您原始示例中对“alert”的调用,它提供了一个数组(从字符串的“Match”方法返回)


Array的“filter”方法在传统浏览器中不受支持,但它很容易进行多填充(如果您只关心像IE9这样的最新支持代理,则当然不需要进行多填充)。

有一个使用正则表达式的单行程序解决方案:

input.match(/([\u4E00-\u9FFF])(?![\s\S]*\1)/g)
但是,我不建议使用它,因为在最坏的情况下(当字符串主要包含中文字符时),它的复杂性为O(n*k),其中n是字符串的长度,k是唯一的中文字符数。为什么是O(n*k)?因为前瞻
(?![\s\s]*\1)
基本上是说“断言在字符串的其余部分的第一个捕获组中找不到任何匹配的另一个实例”


作者@Ruben Kazumov是一个合理的选择。它的复杂性取决于对象中设置和获取属性的实现,在合理的实现中,每个操作的属性都应该是次线性的。

有一种使用正则表达式的单线性解决方案:

input.match(/([\u4E00-\u9FFF])(?![\s\S]*\1)/g)
但是,我不建议使用它,因为在最坏的情况下(当字符串主要包含中文字符时),它的复杂性为O(n*k),其中n是字符串的长度,k是唯一的中文字符数。为什么是O(n*k)?因为前瞻
(?![\s\s]*\1)
基本上是说“断言在字符串的其余部分的第一个捕获组中找不到任何匹配的另一个实例”


作者@Ruben Kazumov是一个合理的选择。它的复杂性取决于在对象中设置和获取属性的实现,在合理的实现中,每个操作的属性都应该是次线性的。

喜欢它!您忘记了返回值
join()
不会影响
ch
谢谢!它起作用了!但至少在Mozilla中,它需要是ch=ch.filter,因为“filter不会改变它所调用的数组”——爱它!您忘记了返回值
join()
不会影响
ch
谢谢!它起作用了!但至少在Mozilla中,它需要是ch=ch.filter,因为“filter不会改变调用它的数组”-为一个非常特定的用例定义一个完整的helper函数是过分的,特别是当它被用来扩展本机JavaScript对象时将在正则表达式中实现,但似乎不是。正则表达式设计用于匹配和/或替换模式。对找到的结果进行排序或过滤不是正则表达式的工作;这些都是像Array这样的接口的责任。为一个非常特定的用例定义一个完整的helper函数是过分的,特别是当它被用来扩展本机JavaScript对象时。我曾认为这样一个简单的任务(R中的unique())会在regex中实现,但它似乎不是。不。正则表达式设计用于匹配和/或替换模式。对找到的结果进行排序或过滤不是正则表达式的工作;这类事情是数组等接口的责任。
我认为如果我在正则表达式内部解决它,速度可能会更快
将其放入正则表达式中可能会得到的边际且不明显的速度提升,不值得为拥有更复杂的正则表达式而费心费力。如果可能的话,将正则表达式拆分。它们很难一目了然地理解,所以任何让它们更具可读性的东西通常都是值得的