2014-11-28 2 views
3

문자열에서 부분 문자열 일치를 찾고 일치하는 위치를 찾으려고했습니다.Swift distance() 메서드가 치명적인 오류를 throw합니다. endIndex를 증가시킬 수 없습니다.

다음 코드 뭐가 잘못 알아낼 수 없습니다 : 제안 된 의견으로

let str1 = "hello#゚Д゚" 
let cmp = "゚Д゚" 
let searchRange = Range(start: str1.startIndex, end: str1.endIndex) 
let range = str1.rangeOfString(cmp, options: .allZeros, range: searchRange) 

println("\(searchRange), \(range!)") // output: 0..<9, 6..<9 

let dis = distance(searchRange.startIndex, range!.startIndex) // fatal error: can not increment endIndex! reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0). 
// let dis = distance(searchRange.startIndex, range!.endIndex) // This will go and output: distance=7 

println("distance=\(dis)") 

을의 range가 유효한 값을 가지고 있지만, 거리() 메소드는 치명적인 오류가 발생했습니다.

distance()를 잘못 사용하면 대상을 보관하는 데 어떤 방법을 사용해야합니까? 조언이 도움이 될 것입니다. 감사. 여기

+0

작동하려면 '거리'에 동일한 컨테이너의 시작 및 끝 범위가 필요합니다. 찾기 기능이 필요하지만 Swift는 원하는 것을 할 수있는 라이브러리가 없습니다. –

+0

무엇을하려고합니까? 하위 문자열의 범위를 얻으시겠습니까? – kap

답변

3

range!.startIndex 포인트 :

"hello#゚Д゚" 
    ^

그러나,이 경우, #゚는 스위프트의 단일 문자입니다. 따라서

,이 코드 :

for var idx = searchRange.startIndex; idx != range!.startIndex; idx = idx.successor() { 
    println("\(idx): \(str1[idx])"); 
} 

인쇄 :

0: h 
1: e 
2: l 
3: l 
4: o 
5: #゚ 
7: Д゚ 
fatal error: Can't form a Character from an empty String 
// and emits BAD_INSTRUCTION exception 

당신이 range!.startIndex 결코 문자 경계에 일치하지 않습니다 볼 수 있듯이, 그리고 for 루프는 문자열을 실행합니다. 그래서 예외가 표시됩니다. String 이후 이론적으로

은,로 " Character의의 컬렉션은"스위프트에, "゚Д゚""hello#゚Д゚"의 하위 안 간주됩니다.

생각해 보면 .rangeOfString()unichar의 시퀀스로 문자열을 처리하는 NSString 구현을 사용합니다. 이것이 버그인지 아닌지는 모르겠습니다.

+0

당신이 맞습니다. "핼프 위드 카타카나 반자동 사운드 마크"는 일종의 결합 캐릭터이며 "# ゚"는 확장 된 제 스팅 클러스터입니다. Swift.String.rangeOfString()은 nil을 반환해야합니다. –

+0

당신의 대답에서, 나는 내가 오해 한 점을 알고 있다고 생각합니다. 나는 distance() 메서드가 무엇이 잘못되었는지 찾아내는 데 주저했지만 스위프트와 코코아 사이에는 불일치가 있다는 것을 잊어 버렸다. 따라서 'rangeOfString'은 Swift 매개 변수를 사용하지만 자체는 Cocoa에서 제공되며 Swift 정책에 위배 될 수 있습니다. 버그가있는 경우에는 'rangeOfString'이어야한다고 동의합니다. 그리고 순수 NSString을 사용하는 것이 해결책이 될 수 있다고 생각합니다. – tyeen

+0

예,이 경우에는 'NSString'과'NSRange'를 사용해야합니다. – rintaro

1

이 시도 :

func search<C: CollectionType where C.Generator.Element: Equatable>(col1: C, col2: C) -> C.Index? { 
    if col2.startIndex == col2.endIndex { 
     return col1.startIndex 
    } 

    var col1Ind = col1.startIndex 
    while col1Ind != col1.endIndex { 
     var ind1 = col1Ind 
     var ind2 = col2.startIndex 
     while col1[ind1] == col2[ind2] { 
      ++ind1; ++ind2 
      if ind2 == col2.endIndex { return col1Ind } 
      if ind1 == col1.endIndex { return nil } 
     } 
     ++col1Ind 
    } 
    return nil 
} 

검색을 COL1에서 COL2 시퀀스의 첫 번째 인스턴스. 발견되었을 경우, 서브 순서의 개시의 인덱스를 돌려줍니다. 발견되지 않으면 nil을 리턴합니다. col2가 하늘의 경우, col1의 startIndex를 돌려줍니다.

관련 문제