我试图在字符串中找到子字符串匹配,并获得匹配的位置。
我无法弄清楚以下代码的错误:
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()方法会引发致命错误。
如果我对distance()的使用有误,我应该用什么方法来存档目标? 任何意见将是有益的。感谢。
答案 0 :(得分:3)
range!.startIndex
点在这里:
"hello#゚Д゚"
^
但是,在这种情况下,#゚
是Swift中的单个字符。
因此,此代码:
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
在Swift中被视为“Character
s的集合”,"゚Д゚"
不应该是"hello#゚Д゚"
的子字符串。
我认为.rangeOfString()
使用NSString
实现,将字符串视为unichar
的序列。我不知道这应该被认为是一个错误。
答案 1 :(得分: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。