2015-01-16 6 views
0

나는 서양과 중국 문자가 혼합 된 텍스트 파일을 가지고 있습니다. 각 파일에 나타나는 중국어 문자 목록을 원합니다.자바 스크립트에서 문자열의 고유 한 문자 목록을 가져 오는 방법은 무엇입니까?

나는 있지만, 일부 반복과,

ch = text.match(/[\u4E00-\u9FFF]/g); // unicode usual chinese characters - that'll do for me 
if (ch != null) { 
    alert(ch); 
} 

이 나에게 중국어 문자의 목록을 제공을 시도했습니다. 예를 들어 :

肉,捕,兵,死,兵,半,水 

파일 서로에 대한

卵,水,半,水,土,木,水,清,慢,底,海,海,海,清,清,清,木,清,慢,底,清,土,半,水,水,土,半,水,土 

에 대한 ...

1) 나는 그 쉼표가 필요하지 않습니다. 저들은 어디서 왔어요? (나는 그들을 하나의 replace로 제거 할 수 있지만, 정규 표현식을 사용하고 있기 때문에 정규 표현식 자체에서 해결하면 더 빠를 것이라고 생각한다.) 2) 유일한 값만 얻는 방법? 예를 들어 첫 번째 파일 두 번째에 대한

卵水半土木清慢底海 

에 대한

肉捕兵死半水 

...

+1

'정규 표현식 자체에서 해결하면 더 빠를 것이라고 생각합니다. 정규 표현식에 넣을 때 얻을 수있는 한계 및 눈에 띄지 않는 속도 향상은 더 복잡한 정규 표현식을 사용하는 데 정신적 인 가치가 없습니다. 가능하면 정규 표현식을 나눕니다. 그들은 한눈에 이해하기가 어려우므로, 읽을 수있게 만드는 것이 그만한 가치가 있습니다. – ajp15243

+0

다른 측면에서, 나는 더 복잡한 정규 표현식을 구성하기 위해 가지고있는 정신적 번거 로움이 한 번 일어났습니다. 내가 할 수있는 스피드 부스트 (테스트하는 것이 중요하다.)는 내가 당신과 의견이 일치하지 않는 여러 번 일어날 것이고이 신사의 디자인 철학에 동의 할 것이다 : www.micosyen.com – Rodrigo

+0

그의 사이트에서 : 25 세기 동안 일관되고 간결하게 적용된 나의 디자인 철학은 단순성보다 더 뛰어난 우아함이 없다는 것입니다. 8 비트는 16 비트보다 16 비트, 16 비트는 32 비트보다 더 선호됩니다. 5MHz 클록이 50보다 높고 50이 500보다 더 좋습니다. 조립이 선호됩니다 C over C, C++ C++ 하드웨어의 부 풀기 제거는 하드웨어의 부풀림을 제거하는 열쇠입니다. 하드웨어의 팽창을 제거하는 것은 혁신, 성능 및 비용면에서 찬사를 얻으려고 평범함의 불협화음 이상으로 상승하는 제품을 만드는 열쇠입니다. 유효성." – Rodrigo

답변

2

쉼표는 문자열 변환에 기본 배열에서 왔습니다. 배열을 문자열로 변환하려면 ch.join('')을 사용하십시오.

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

그것을 좋아해라! 당신은 가치를 반환하는 것을 잊어 버립니다. 'join()'은'ch'에 영향을 미치지 않습니다 –

+0

고마워요! 그것은 작동합니다! 하지만 적어도 Mozilla에서는 ch = ch.filter 여야합니다. "필터가 호출되는 배열을 변경하지 않기 때문에"- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/ Global_Objects/Array/filter – Rodrigo

2
Array.prototype.getUnique = function(){ 
    var u = {}, a = []; 
    for(var i = 0, l = this.length; i < l; ++i){ 
     if(u.hasOwnProperty(this[i])) { 
     continue; 
     } 
     a.push(this[i]); 
     u[this[i]] = 1; 
    } 
    return a; 
} 


ch = text.match(/([\u4E00-\u9FFF])/g); 
var result_string = ch.getUnique().join(""); 
+0

아주 특별한 유스 케이스에 대한 전체 도우미 함수를 정의하는 것은 잔인합니다. 특히 네이티브 JavaScript 객체를 확장하는 데 사용되는 경우 특히 그렇습니다. – Alhadis

+0

나는 사소한 작업 (R에서 unique())이 정규 표현식 내부에서 구현 될 것이라고 생각했지만 그렇지 않은 것 같습니다. – Rodrigo

+1

아니요. 정규식은 패턴 일치 또는 대체를 위해 설계되었습니다. 발견 한 결과를 정렬하거나 필터링하는 것은 정규식 작업이 아닙니다. 이러한 일은 Array와 같은 인터페이스의 책임입니다. – Alhadis

1

이 시도 :

사용이 줄을 중복 값을 제거하려면

["卵", "水", "半", "土", "木", "清", "慢", "底", "海"] 

그리고 네, 쉼표 당신 ': 반환

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(""); 

다시 볼 때 브라우저가 배열을 string : 각 값의 문자열 표현을 쉼표로 결합합니다. 나는 원래의 예제에서 배열 (문자열의 "Match"메서드에서 반환 됨)이 제공되는 "alert"호출에서 온 것 같아요.

어레이의 "필터"방법은 레거시 브라우저에서 지원되지 않지만 polyfill은 매우 쉽습니다 (IE9와 같은 최근의 에이전트 만 지원하는 경우에는 필요하지 않습니다).

0

이 정규식과 한 줄 솔루션 :이 O이 때문에

input.match(/([\u4E00-\u9FFF])(?![\s\S]*\1)/g) 

그러나, 나는 그것을를 사용하는 것이 좋습니다 않을 것이다 (N * k)는 최악의 경우 복잡합니다 (문자열은 주로 한자를 포함합니다). 여기서 n은 문자열의 길이이고 k는 고유 한자 수입니다. 왜 O (n * k)입니까? 미리보기 (?![\s\S]*\1)은 기본적으로 "문자열의 나머지 부분에서 첫 번째 캡처 그룹에 일치하는 것이 무엇이든 다른 인스턴스를 찾을 수 없다는 것을 주장합니다"라고 말합니다.

This answer by @Ruben Kazumov는 합리적인 대안입니다.그 복잡성은 객체의 설정 및 구현의 구현에 따라 달라지며, 이는 합리적인 구현에서 작업 당 부 선형이어야합니다.