2016-09-06 10 views
1

와 이상한 결과를 반환 내가 태국어를 말하지 않기 때문에 - 감각적 인 테스트.NSString.rangeOfString 내가 예를 들어, 문자열에서 두 단어의 범위를 얻을 필요가 비 라틴 문자

//Find all the ranges of each word 
var words: [String] = [] 
var ranges: [NSRange] = [] 

//Convert to nsstring first because otherwise you get stuck with Ranges and Strings. 
let nstext = backgroundTextField.stringValue as NSString //contains "ยัฟิแก ไฟหก" 
words = nstext.componentsSeparatedByString(" ") 
var nstextLessWordsWeHaveRangesFor = nstext //if you have two identical words this prevents just getting the first word's range 

for word in words 
     { 

      let range:NSRange = nstextLessWordsWeHaveRangesFor.rangeOfString(word) 
      Swift.print(range) 
      ranges.append(range) 

      //create a string the same length as word 
      var fillerString:String = "" 

      for i in 0..<word.characters.count{ 
      //for var i=0;i<word.characters.count;i += 1{ 
       Swift.print("i: \(i)") 
       fillerString = fillerString.stringByAppendingString(" ") 
      } 

      //remove duplicate words/letters so that we get correct range each time. 
      if range.length <= nstextLessWordsWeHaveRangesFor.length 
      { 
       nstextLessWordsWeHaveRangesFor = nstextLessWordsWeHaveRangesFor.stringByReplacingCharactersInRange(range, withString: fillerString) 
      }    
     } 

출력 : 그 범위가 겹치는

(0,6) 
(5,4) 

.

범위가 일치하지 않아 NSLayoutManager.enumerateEnclosingRectsForGlyphRange을 사용하려고하는 문제가 발생합니다.

정확한 범위 (또는 특정 경우 넌 - 중복 범위)를 얻으려면 어떻게해야합니까?

+2

으로 단순화 될 수 있습니다. 코드에는 print 문이 하나만 있습니다. 두 개의 출력 행을 얻으려면 어떻게해야합니까? –

+0

사실상 의사 코드인데 문제를 격리하려고합니다. 응용 프로그램에서 문자열의 단어를 순환합니다. – glenstorey

+0

문제를 보여주는 재현성 있고 독립적 인 예가 도움이 될 것입니다. 그것에 –

답변

3

스위프트 String 문자 "확장 된 자모 클러스터"를 설명하며 NSString 은 UTF-16 코드 포인트를 사용하므로, 여기서 중복 단어 제거는 제거 된 결과는 문자열의 길이는 사용하는 표현에 따라 과 다릅니다.

예를 들어, 첫 번째 문자 "ยั" 실제로 구별 표시 " ั" (U + 0E31)와 "ย" (U + 0E22)의 조합 이다. 숫자는 String이지만 숫자는 NSString입니다. 따라서 단어를 공백으로 바꿀 때 색인이 변경됩니다.

가장 간단한 해결책은 String 또는 NSString (가능한 경우) 중 하나에 붙이는 것입니다. 당신이

for i in 0..<range.length { 

for i in 0..<word.characters.count { 

을 변경, NSString 작업을하고 있기 때문에 문제를 해결해야한다. 필러 문자열 의 생성은

//create a string the same length as word 
let fillerString = String(count: range.length, repeatedValue: Character(" ")) 
1

nstextLessWordsWeHaveRangesFor을 제거하면 문제가 해결됩니다 (하단의 range.length <= nstextLessWordsWeHaveRangesFor.length으로 시작). 변수의 수정은 범위를 변경하고 예기치 않은 결과를 제공합니다.

var words: [String] = [] 

let nstext = "ยัฟิแก ไฟหก" as NSString 
words = nstext.componentsSeparatedByString(" ") 

for word in words { 
    let range = nstext.rangeOfString(word) 
    print(range) 
} 

출력된다 : (0,6)(7,4)