我从网站获取数据(HTML字符串)。我想提取所有链接。我写函数(它工作),但它是如此缓慢.
你能帮我优化一下吗?我可以使用哪些标准功能?功能逻辑:在文本中找到“http:.//”sting,然后读取string(buy char),直到我不会得到“""。
extension String {
subscript (i: Int) -> Character {
return self[advance(self.startIndex, i)]
}
subscript (i: Int) -> String {
return String(self[i] as Character)
}
subscript (r: Range<Int>) -> String {
return substringWithRange(Range(start: advance(startIndex, r.startIndex), end: advance(startIndex, r.endIndex)))
}}
func extractAllLinks(text:String) -> Array<String>{
var stringArray = Array<String>()
var find = "http://" as String
for (var i = countElements(find); i<countElements(text); i++)
{
var ch:Character = text[i - Int(countElements(find))]
if (ch == find[0])
{
var j = 0
while (ch == find[j])
{
var ch2:Character = find[j]
if(countElements(find)-1 == j)
{
break
}
j++
i++
ch = text[i - Int(countElements(find))]
}
i -= j
if (j == (countElements(find)-1))
{
var str = ""
for (; text[i - Int(countElements(find))] != "\""; i++)
{
str += text[i - Int(countElements(find))]
}
stringArray.append(str)
}
}
}
return stringArray}
8条答案
按热度按时间relj7zay1#
就像AdamPro13上面说的使用
NSDataDetector
就可以很容易的得到所有的URL,看下面的代码吧:它输出:
更新到Swift 2.0
记住在上面的情况下使用
guard
语句,它必须在函数或循环中。我希望这对你有帮助。
fdx2calv2#
这就是Swift 5.0的答案
rm5edbpk3#
详情
解决方案
用法
控制台输出
vnzz0bqm4#
非常有用的线程!下面是一个在Swift 1.2中工作的示例,基于Victor Sigler的答案。
dpiehjr45#
实际上有一个名为
NSDataDetector
的类可以为您检测链接。你可以在NSHipster上找到一个例子:http://nshipster.com/nsdatadetector/
vbopmzt16#
我想知道你是否意识到,每次调用countElements时,都会调用一个主要的复杂函数,该函数必须扫描字符串中的所有Unicode字符,并从中提取扩展的字形簇并对其进行计数。如果你不知道什么是扩展字素簇,那么你应该能够想象,这是不便宜和主要矫枉过正。
只需将其转换为NSString*,调用rangeOfString并完成它。
很明显,你所做的是完全不安全的,因为http://并不意味着有一个链接。你不能只是在html中寻找字符串并希望它能工作;不是的然后是https,Http,hTtp,htTp,https等等等等。但这一切都很容易,真实的的恐怖遵循乌塔姆辛哈的评论链接。
idv4meu87#
正如其他人所指出的,最好使用正则表达式、数据检测器或解析库。然而,作为对字符串处理的具体反馈:
Swift字符串的关键是接受它们的只向前性质。通常,整数索引和随机访问是不必要的。正如@gnasher729所指出的,每次调用
count
时,都是在迭代字符串。类似地,整数索引扩展是线性的,因此如果在循环中使用它们,很容易意外地创建二次或三次复杂度算法。但在本例中,不需要将字符串索引转换为随机访问整数。下面是一个我认为执行类似逻辑的版本(查找前缀,然后从那里查找“字符-忽略这不适合https,大写/小写等),只使用本地字符串索引:
如果有其他助手,如
findFromIndex
等,甚至可以进一步优化(advance(idx, count())
有点低效)。或者愿意不使用字符串片段而手动滚动搜索结束字符。mxg2im7a8#
Swift 5.8.1
用法: