我还没有弄清楚如何String
在Swift中获取a的子串:
var str = “Hello, playground” func test(str: String) -> String { return str.substringWithRange( /* What goes here? */ ) } test (str)
我无法在Swift中创建一个Range.游乐场中的自动填充功能并不是非常有用 - 这就是它的建议:
return str.substringWithRange(aRange: Range)
我没有在Swift标准参考库中找到任何有帮助的内容.这是另一个疯狂的猜测:
return str.substringWithRange(Range(0, 1))
还有这个:
let r:Range= Range (start: 0, end: 2) return str.substringWithRange(r)
我已经看到其他答案(查找Swift字符串中的字符索引)似乎表明,因为它String
是一种桥接类型NSString
,"旧"方法应该有效,但是不清楚如何 - 例如,这也不起作用(似乎不是有效的语法):
let x = str.substringWithRange(NSMakeRange(0, 3))
思考?
您可以使用substringWithRange方法.它需要一个开始和结束String.Index.
var str = "Hello, playground" str.substringWithRange(Range<String.Index>(start: str.startIndex, end: str.endIndex)) //"Hello, playground"
要更改开始和结束索引,请使用advancedBy(n).
var str = "Hello, playground" str.substringWithRange(Range<String.Index>(start: str.startIndex.advancedBy(2), end: str.endIndex.advancedBy(-1))) //"llo, playgroun"
你仍然可以在NSRange中使用NSString方法,但是你必须确保使用这样的NSString:
let myNSString = str as NSString myNSString.substringWithRange(NSRange(location: 0, length: 3))
注意:正如JanX2所提到的,第二种方法对于unicode字符串是不安全的.
在我写作的时候,没有任何扩展与Swift 4.2兼容,所以这里有一个涵盖了我能想到的所有需求:
extension String { func substring(from: Int?, to: Int?) -> String { if let start = from { guard start < self.count else { return "" } } if let end = to { guard end >= 0 else { return "" } } if let start = from, let end = to { guard end - start >= 0 else { return "" } } let startIndex: String.Index if let start = from, start >= 0 { startIndex = self.index(self.startIndex, offsetBy: start) } else { startIndex = self.startIndex } let endIndex: String.Index if let end = to, end >= 0, end < self.count { endIndex = self.index(self.startIndex, offsetBy: end + 1) } else { endIndex = self.endIndex } return String(self[startIndex ..< endIndex]) } func substring(from: Int) -> String { return self.substring(from: from, to: nil) } func substring(to: Int) -> String { return self.substring(from: nil, to: to) } func substring(from: Int?, length: Int) -> String { guard length > 0 else { return "" } let end: Int if let start = from, start > 0 { end = start + length - 1 } else { end = length - 1 } return self.substring(from: from, to: end) } func substring(length: Int, to: Int?) -> String { guard let end = to, end > 0, length > 0 else { return "" } let start: Int if let end = to, end - length > 0 { start = end - length + 1 } else { start = 0 } return self.substring(from: start, to: to) } }
然后,您可以使用:
let string = "Hello,World!"
string.substring(from: 1, to: 7)
得到你: ello,Wo
string.substring(to: 7)
得到你: Hello,Wo
string.substring(from: 3)
得到你: lo,World!
string.substring(from: 1, length: 4)
得到你: ello
string.substring(length: 4, to: 7)
得到你: o,Wo
更新substring(from: Int?, length: Int)
以支持从零开始.
一旦找到正确的语法,它就比这里的任何答案简单得多.
我想带走[和]
let myString = "[ABCDEFGHI]" let startIndex = advance(myString.startIndex, 1) //advance as much as you like let endIndex = advance(myString.endIndex, -1) let range = startIndex..<endIndex let myNewString = myString.substringWithRange( range )
结果将是"ABCDEFGHI",startIndex和endIndex也可用于
let mySubString = myString.substringFromIndex(startIndex)
等等!
PS:正如备注中所示,swift 2中有一些语法更改,包括xcode 7和iOS9!
请看这个页面
SWIFT 2.0
简单:
let myString = "full text container" let substring = myString[myString.startIndex..<myString.startIndex.advancedBy(3)] // prints: ful
SWIFT 3.0
let substring = myString[myString.startIndex..<myString.index(myString.startIndex, offsetBy: 3)] // prints: ful
SWIFT 4.0
子串操作返回Substring类型的实例,而不是String.
let substring = myString[myString.startIndex..<myString.index(myString.startIndex, offsetBy: 3)] // prints: ful // Convert the result to a String for long-term storage. let newString = String(substring)
简单
let str = "My String" let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)] //"Strin"
let startIndex = str.index(str.startIndex, offsetBy: 3) let endIndex = str.index(str.startIndex, offsetBy: 7) str[startIndex...endIndex] // "Strin" str.substring(to: startIndex) // "My " str.substring(from: startIndex) // "String"
substring(to:)
并且substring(from:)
已弃用Swift 4
.
String(str[..<startIndex]) // "My " String(str[startIndex...]) // "String" String(str[startIndex...endIndex]) // "Strin"
例如,以我的全名查找名字(直到第一个空格):
let name = "Joris Kluivers" let start = name.startIndex let end = find(name, " ") if end { let firstName = name[start..end!] } else { // no space found }
start
并且end
在String.Index
这里是类型Range<String.Index>
,用于在下标访问器中创建和使用(如果在原始字符串中找到空格).
很难String.Index
直接从开头文章中使用的整数位置创建.这是因为在我的名字中,每个字符的大小都是相等的.但是在其他语言中使用特殊重音的字符可能使用了几个字节(取决于所使用的编码).那么整数应该指的是什么字节?
可以String.Index
使用这些方法从现有方法创建一个新的succ
,pred
这将确保跳过正确的字节数以到达编码中的下一个代码点.但是在这种情况下,更容易搜索字符串中第一个空格的索引以查找结束索引.
在新的Xcode 7.0中使用
//: Playground - noun: a place where people can play import UIKit var name = "How do you use String.substringWithRange?" let range = name.startIndex.advancedBy(0)..<name.startIndex.advancedBy(10) name.substringWithRange(range) //OUT:
由于String是NSString的桥接类型,"旧"方法应该可以工作,但是不清楚如何 - 例如,这也不起作用(似乎不是有效的语法):
let x = str.substringWithRange(NSMakeRange(0, 3))
对我来说,这是你问题中非常有趣的部分.字符串被桥接到的NSString,所以大多数的NSString方法都在一根绳子上直接工作.您可以自由地使用它们而无需考虑.因此,例如,这可以像您期望的那样工作:
// delete all spaces from Swift String stateName stateName = stateName.stringByReplacingOccurrencesOfString(" ", withString:"")
但是,正如经常发生的那样,"我得到了我的魔力,但它对你不起作用." 你碰巧选择了一种罕见的情况,其中存在一个并行的同名Swift方法,在这种情况下,Swift方法掩盖了Objective-C方法.因此,当你说str.substringWithRange
,Swift认为你的意思是Swift方法而不是NSString方法 - 然后你就被软管了,因为Swift方法需要一个Range<String.Index>
,而你不知道如何制作其中一个.
最简单的方法是通过显式转换来阻止Swift像这样黯然失色:
let x = (str as NSString).substringWithRange(NSMakeRange(0, 3))
请注意,此处不涉及重要的额外工作."演员"并不意味着"转换"; String 实际上是一个NSString.我们只是告诉Swift如何在这一行代码中查看此变量.
整个事情中非常奇怪的部分是导致所有这些麻烦的Swift方法没有记录.我不知道它的定义在哪里; 它不在NSString头中,也不在Swift头中.
有关如何在Swift 2.0中获取子字符串的示例代码
(i)起始索引的子串
输入: -
var str = "Swift is very powerful language!" print(str) str = str.substringToIndex(str.startIndex.advancedBy(5)) print(str)
输出: -
Swift is very powerful language! Swift
(ii)来自特定指数的子串
输入: -
var str = "Swift is very powerful language!" print(str) str = str.substringFromIndex(str.startIndex.advancedBy(6)).substringToIndex(str.startIndex.advancedBy(2)) print(str)
输出: -
Swift is very powerful language! is
我希望它会对你有所帮助!
简短的回答是,现在Swift真的很难.我的预感是苹果仍然有很多工作要做方便的方法来做这样的事情.
String.substringWithRange()
期待一个Range<String.Index>
参数,据我所知,该String.Index
类型没有生成器方法.你可以String.Index
从它们那里得到价值,aString.startIndex
然后aString.endIndex
再打电话.succ()
或者打电话.pred()
给他们,但这很疯狂.
如果String类上的扩展需要很好的旧Int
s?
extension String { subscript (r: Range<Int>) -> String { get { let subStart = advance(self.startIndex, r.startIndex, self.endIndex) let subEnd = advance(subStart, r.endIndex - r.startIndex, self.endIndex) return self.substringWithRange(Range(start: subStart, end: subEnd)) } } func substring(from: Int) -> String { let end = countElements(self) return self[from..<end] } func substring(from: Int, length: Int) -> String { let end = from + length return self[from..<end] } } let mobyDick = "Call me Ishmael." println(mobyDick[8...14]) // Ishmael let dogString = "This 's name is Patch." println(dogString[5..<6]) // println(dogString[5...5]) // println(dogString.substring(5)) // 's name is Patch. println(dogString.substring(5, length: 1)) //
更新: Swift beta 4解决了以下问题!
由于它处于[beta 3及更早版本],即使是Swift本地字符串也存在处理Unicode字符的一些问题.上面的狗图标工作,但以下不是:
let harderString = "1:1??" for character in harderString { println(character) }
输出:
1 : 1 ? ?
您可以使用此扩展程序进行改进 substringWithRange
斯威夫特2.3
extension String { func substringWithRange(start: Int, end: Int) -> String { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if end < 0 || end > self.characters.count { print("end index \(end) out of bounds") return "" } let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(end)) return self.substringWithRange(range) } func substringWithRange(start: Int, location: Int) -> String { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if location < 0 || start + location > self.characters.count { print("end index \(start + location) out of bounds") return "" } let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(start + location)) return self.substringWithRange(range) } }
斯威夫特3
extension String { func substring(start: Int, end: Int) -> String { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if end < 0 || end > self.characters.count { print("end index \(end) out of bounds") return "" } let startIndex = self.characters.index(self.startIndex, offsetBy: start) let endIndex = self.characters.index(self.startIndex, offsetBy: end) let range = startIndex..<endIndex return self.substring(with: range) } func substring(start: Int, location: Int) -> String { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if location < 0 || start + location > self.characters.count { print("end index \(start + location) out of bounds") return "" } let startIndex = self.characters.index(self.startIndex, offsetBy: start) let endIndex = self.characters.index(self.startIndex, offsetBy: start + location) let range = startIndex..<endIndex return self.substring(with: range) } }
用法:
let str = "Hello, playground" let substring1 = str.substringWithRange(0, end: 5) //Hello let substring2 = str.substringWithRange(7, location: 10) //playground
这适用于我的操场:)
String(seq: Array(str)[2...4])
更新了Xcode 7.添加字符串扩展名:
使用:
var chuck: String = "Hello Chuck Norris" chuck[6...11] // => Chuck
执行:
extension String { /** Subscript to allow for quick String substrings ["Hello"][0...1] = "He" */ subscript (r: Range<Int>) -> String { get { let start = self.startIndex.advancedBy(r.startIndex) let end = self.startIndex.advancedBy(r.endIndex - 1) return self.substringWithRange(start..<end) } } }
使用少量代码轻松解决问题
制作一个包含几乎所有其他语言都具有的基本subStringing的扩展:
extension String { func subString(start: Int, end: Int) -> String { let startIndex = self.index(self.startIndex, offsetBy: start) let endIndex = self.index(startIndex, offsetBy: end) let finalString = self.substring(from: startIndex) return finalString.substring(to: endIndex) } }
简单地称之为
someString.subString(start: 0, end: 6)
注意:@airspeedswift 对这种方法的权衡取得了一些非常有见地的观点,尤其是隐藏的性能影响.字符串不是简单的野兽,并且到达特定索引可能花费O(n)时间,这意味着使用下标的循环可以是O(n ^ 2).你被警告了.
您只需添加一个新subscript
功能,该功能需要一个范围并用于advancedBy()
步行到您想要的位置:
import Foundation extension String { subscript (r: Range<Int>) -> String { get { let startIndex = self.startIndex.advancedBy(r.startIndex) let endIndex = startIndex.advancedBy(r.endIndex - r.startIndex) return self[Range(start: startIndex, end: endIndex)] } } } var s = "Hello, playground" println(s[0...5]) // ==> "Hello," println(s[0..<5]) // ==> "Hello"
(这绝对应该是语言的一部分.请填写:rdar:// 17158813)
为了好玩,您还可以+
在索引上添加运算符:
func +<T: ForwardIndex>(var index: T, var count: Int) -> T { for (; count > 0; --count) { index = index.succ() } return index } s.substringWithRange(s.startIndex+2 .. s.startIndex+5)
(我还不知道这个是否应该成为该语言的一部分.)