Ios 是否可以使用NSDataDetector检测NSString中包含空格的链接?
首先,我无法控制我收到的文本。我只是想说出来,让你知道我不能改变链接 我试图使用Ios 是否可以使用NSDataDetector检测NSString中包含空格的链接?,ios,objective-c,regex,nsdatadetector,Ios,Objective C,Regex,Nsdatadetector,首先,我无法控制我收到的文本。我只是想说出来,让你知道我不能改变链接 我试图使用NSDataDetector查找链接的文本包含以下内容: <h1>My main item</h1> <img src="http://www.blah.com/My First Image Here.jpg"> <h2>Some extra data</h2> 这是苹果链接检测的一个错误,它无法检测到带有空格的链接,还是我做错了什么 是否有人有更可靠的方
NSDataDetector
查找链接的文本包含以下内容:
<h1>My main item</h1>
<img src="http://www.blah.com/My First Image Here.jpg">
<h2>Some extra data</h2>
这是苹果链接检测的一个错误,它无法检测到带有空格的链接,还是我做错了什么
是否有人有更可靠的方法来检测链接,而不管链接中是否包含空格、特殊字符或其他内容?您可以使用空格将字符串拆分为多个片段,这样您就拥有了一个没有空格的字符串数组。然后,您可以将这些字符串中的每一个输入到数据检测器中
// assume str = <img src="http://www.blah.com/My First Image Here.jpg">
NSArray *components = [str componentsSeparatedByString:@" "];
for (NSString *strWithNoSpace in components) {
// feed strings into data detector
}
//假设str=
NSArray*components=[str componentsSeparatedByString:@”“];
用于(组件中的NSString*strWithNoSpace){
//将字符串输入数据检测器
}
另一种选择是专门查找该HTML标记。不过,这是一个不太通用的解决方案
// assume that those 3 HTML strings are in a string array called strArray
for (NSString *htmlLine in strArray) {
if ([[htmlLine substringWithRange:NSMakeRange(0, 8)] isEqualToString:@"<img src"]) {
// Get the url from the img src tag
NSString *urlString = [htmlLine substringWithRange:NSMakeRange(10, htmlLine.length - 12)];
}
}
//假设这3个HTML字符串位于名为strArray的字符串数组中
用于(NSString*strArray中的HTMLINE){
如果([[HTMLINE substringWithRange:NSMakeRange(0,8)]isEqualToString:@“我找到了一种非常棘手的方法来解决我的问题。如果有人提出了一种更好的解决方案,可以应用于所有URL,请这样做
因为我只关心有这个问题的以.jpg
结尾的URL,所以我找到了一个很好的方法来追踪这个问题
从本质上讲,我将字符串分解成以“http://
开头的组件,并将其分解成一个数组。然后我在该数组中循环执行另一个分解,以查找.jpg”
。当.jpg>开始时,内部数组的计数将仅为>1
>
字符串被找到。然后我保留我找到的字符串和我用%20
替换来修复的字符串,并使用它们对原始字符串进行最后的字符串替换
它不是完美的,也可能效率低下,但它完成了我需要的工作
- (NSString *)replaceSpacesInJpegURLs:(NSString *)htmlString
{
NSString *newString = htmlString;
NSArray *array = [htmlString componentsSeparatedByString:@"\"http://"];
for (NSString *str in array)
{
NSArray *array2 = [str componentsSeparatedByString:@".jpg\""];
if ([array2 count] > 1)
{
NSString *stringToFix = [array2 objectAtIndex:0];
NSString *fixedString = [stringToFix stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
newString = [newString stringByReplacingOccurrencesOfString:stringToFix withString:fixedString];
}
}
return newString;
}
您不应该将NSDataDetector与HTML一起使用。它用于解析普通文本(由用户输入),而不是计算机生成的数据(事实上,它有许多启发式方法来确保它不会检测到计算机生成的可能与用户无关的内容)
如果你的字符串是HTML,那么你应该使用HTML解析库。有很多开源工具包可以帮助你做到这一点。然后只需抓取锚的href属性,或者在文本节点上运行NSDataDetector,就可以找到没有标记的内容,而不会用标记污染字符串。URL确实不应该包含空格。我会删除一个在执行与字符串相关的任何URL操作之前,先从字符串中删除空格,如下所示
// Custom function which cleans up strings ready to be used for URLs
func cleanStringForURL(string: NSString) -> NSString {
var temp = string
var clean = string.stringByReplacingOccurrencesOfString(" ", withString: "")
return clean
}
您可以使用NSRegularExpression
来修复所有URL,方法是使用一个简单的正则表达式来检测链接,然后只对空格进行编码(如果需要更复杂的编码,您可以通过添加百分比转义来查看CFURLCreateStringByAddingPercentEscapes
,这里有很多示例)。如果您以前没有使用过NSRegularExpression
,那么可能需要花费一些时间的唯一一件事就是如何迭代结果并进行替换,下面的代码应该可以做到这一点:
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"src=\".*\"" options:NSRegularExpressionCaseInsensitive error:&error];
if (!error)
{
NSInteger offset = 0;
NSArray *matches = [regex matchesInString:myHTML options:0 range:NSMakeRange(0, [myHTML length])];
for (NSTextCheckingResult *result in matches)
{
NSRange resultRange = [result range];
resultRange.location += offset;
NSString *match = [regex replacementStringForResult:result inString:myHTML offset:offset template:@"$0"];
NSString *replacement = [match stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
myHTML = [myHTML stringByReplacingCharactersInRange:resultRange withString:replacement];
offset += ([replacement length] - resultRange.length);
}
}
我刚刚收到苹果公司对我在这方面提出的一个错误的回复:
我们相信这个问题已经在最新的iOS 9测试版中得到解决。
这是预发布的iOS 9更新
有关完整安装,请参阅发行说明
指示
请使用此版本进行测试。如果仍然存在问题,请
提供任何可以帮助我们的相关日志或信息
调查
iOS 9
我将测试并让大家知道iOS 9是否修复了此问题。尝试此正则表达式模式:@“]*>“
忽略大小写…匹配源url的索引=2
javascript中的正则表达式演示:(请尝试获取任何帮助)
尝试一下这个片段(我从您的第一位评论员用户3584460处获得了regexp):
这需要是动态的,而不仅仅是硬编码到这个URL。在这个字符串中可以有多个不同长度的URL,并且所有URL中都可以有空格。我很感激这个答案,但是你能在一些文档中告诉我,不应该在HTML上使用NSDataDetector
?这样我就知道这是真的。这是answer真的很好……但我想你不知道你最后的评论给人留下了什么样的印象。因为你在苹果工作,我恳请你更新文档,以反映你答案中的细节。我不知道NSDataDetector是“用于解析普通文本”(无论“正常”是什么)的,而且“有很多启发式方法来确保它不会检测到计算机生成的东西”,苹果也没有描述这到底意味着什么……什么是“计算机生成的东西”?请把这个推到你们的文档上。我已经在这上面浪费了好几个小时,而合适的文档本来可以救我的。@Zero我知道他的意思”普通文本",但当有人谈论非常技术性的逻辑软件开发时,你不能用含糊不清的陈述来解释。我需要苹果公司具体告诉我在使用探测器时什么是允许的,什么是不允许的。这是我的问题。我可能会对一家小公司置之不理,但苹果是世界上最有价值的公司…这里没有任何借口。我已经提交了一个bug来改进文档。没有办法…字符串是一个巨大的HTML页面。我无法删除整个页面中的所有空格。我只需要修复URL。而且,许多网站都有带有空格的URL,不管它们是否应该。在我的情况下,我无法控制这个问题HTML的ce。正则表达式如何;例如,regularExpressionWithPatter
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"src=\".*\"" options:NSRegularExpressionCaseInsensitive error:&error];
if (!error)
{
NSInteger offset = 0;
NSArray *matches = [regex matchesInString:myHTML options:0 range:NSMakeRange(0, [myHTML length])];
for (NSTextCheckingResult *result in matches)
{
NSRange resultRange = [result range];
resultRange.location += offset;
NSString *match = [regex replacementStringForResult:result inString:myHTML offset:offset template:@"$0"];
NSString *replacement = [match stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
myHTML = [myHTML stringByReplacingCharactersInRange:resultRange withString:replacement];
offset += ([replacement length] - resultRange.length);
}
}
NSError *error = NULL;
NSString *myHTML = @"<http><h1>My main item</h1><img src=\"http://www.blah.com/My First Image Here.jpg\"><h2>Some extra data</h2><img src=\"http://www.bloh.com/My Second Image Here.jpg\"><h3>Some extra data</h3><img src=\"http://www.bluh.com/My Third-Image Here.jpg\"></http>";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"src=[\"'](.+?)[\"'].*?>" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *arrayOfAllMatches = [regex matchesInString:myHTML options:0 range:NSMakeRange(0, [myHTML length])];
NSTextCheckingResult *match = [regex firstMatchInString:myHTML options:0 range:NSMakeRange(0, myHTML.length)];
for (NSTextCheckingResult *match in arrayOfAllMatches) {
NSRange range = [match rangeAtIndex:1];
NSString* substringForMatch = [myHTML substringWithRange:range];
NSLog(@"Extracted URL : %@",substringForMatch);
}
Extracted URL : http://www.blah.com/My First Image Here.jpg
Extracted URL : http://www.bloh.com/My Second Image Here.jpg
Extracted URL : http://www.bluh.com/My Third-Image Here.jpg