Swift 5.1-是否有一种干净的方法来处理子字符串/模式匹配的位置
我对Swift非常、非常陌生,并且承认我正在为它的一些结构而挣扎。我必须处理一个文本文件并进行许多操作-以下是一个示例来说明这一点: 假设我有这样一个文本(多行) 我希望能够做一些简单的事情,比如找到@name的位置,然后拆分它以获得名称等等。我已经在javascript中完成了这项工作,使用substr和正则表达式匹配非常简单 在斯威夫特,这应该是迅速和容易的,什么都不是,我发现这是非常混乱 有人能帮助我们做些什么吗Swift 5.1-是否有一种干净的方法来处理子字符串/模式匹配的位置,swift,string,substring,swift5,Swift,String,Substring,Swift5,我对Swift非常、非常陌生,并且承认我正在为它的一些结构而挣扎。我必须处理一个文本文件并进行许多操作-以下是一个示例来说明这一点: 假设我有这样一个文本(多行) 我希望能够做一些简单的事情,比如找到@name的位置,然后拆分它以获得名称等等。我已经在javascript中完成了这项工作,使用substr和正则表达式匹配非常简单 在斯威夫特,这应该是迅速和容易的,什么都不是,我发现这是非常混乱 有人能帮助我们做些什么吗 查找子字符串开头的位置 提取从子字符串结尾到文本结尾之间的所有文本 抱歉,如
抱歉,如果这是琐碎的-但苹果的文档感觉非常复杂,而且很多例子都有好几年的历史了。我似乎也找不到简单的regex应用程序。您可以使用
range()
和distance()
:
您可以使用string range(of:string)方法查找字符串的范围,获取其上限,并从字符串的该位置搜索行尾:
操场测试:
let sentence = """
Mary had a little lamb
@name: a name
@summary: a paragraph of text
{{something}}
a whole bunch of multi-line text
"""
如果您发现自己经常使用它,您可以扩展StringProtocol并创建自己的方法:
extension StringProtocol {
func substring<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> SubSequence? {
guard
let lower = range(of: start, options: options)?.upperBound,
let upper = self[lower...].range(of: end, options: options)?.lowerBound
else { return nil }
return self[lower..<upper]
}
func substring<S:StringProtocol>(after string: S, options: String.CompareOptions = []) -> SubSequence? {
guard
let lower = range(of: string, options: options)?.upperBound else { return nil }
return self[lower...]
}
}
您也可以使用正则表达式:
let name = sentence.substring(between: "@\\w+:", and: "\\n", options: .regularExpression) // " a name"
“提取从子字符串结尾到文本结尾之间的所有文本”:您是指子字符串的开头吗?OP对Swift来说是新的。如果文本中没有“amp”范围,则会使应用程序崩溃。我想我可以在执行某些操作之前使用.contains()添加一些检查。。。哇!这是非常有用和有益的,谢谢你。我正在慢慢地掌握它,但还不完全掌握。文档语法让我很反感——当我在swift中阅读函数文档时,我很难将其转换为实际代码。也许这是一个习惯的问题,看看这样的例子。如果你需要找到所有的例子
if let start = sentence.range(of: "@name:")?.upperBound,
let end = sentence[start...].range(of: "\n")?.lowerBound {
let substring = sentence[start..<end]
print("name:", substring)
}
if let start = sentence.range(of: "@summary:")?.upperBound {
let substring = sentence[start...]
print("summary:", substring)
}
extension StringProtocol {
func substring<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> SubSequence? {
guard
let lower = range(of: start, options: options)?.upperBound,
let upper = self[lower...].range(of: end, options: options)?.lowerBound
else { return nil }
return self[lower..<upper]
}
func substring<S:StringProtocol>(after string: S, options: String.CompareOptions = []) -> SubSequence? {
guard
let lower = range(of: string, options: options)?.upperBound else { return nil }
return self[lower...]
}
}
let name = sentence.substring(between: "@name:", and: "\n") // " a name"
let sumary = sentence.substring(after: "@summary:") // " a paragraph of text\n\n{{something}}\n\na whole bunch of multi-line text"
let name = sentence.substring(between: "@\\w+:", and: "\\n", options: .regularExpression) // " a name"