Можно ли обнаружить ссылки в NSString с пробелами в них с помощью NSDataDetector?
Во-первых, я не могу контролировать текст, который я получаю. Просто хотел поместить это там, чтобы вы знали, что я не могу изменить ссылки.
Текст, который я пытаюсь найти в использовании NSDataDetector
, содержит следующее:
<h1>My main item</h1>
<img src="http://www.blah.com/My First Image Here.jpg">
<h2>Some extra data</h2>
Код обнаружения, который я использую, это, но он не найдет эту ссылку:
NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray *matches = [linkDetector matchesInString:myHTML options:0 range:NSMakeRange(0, [myHTML length])];
for (NSTextCheckingResult *match in matches)
{
if ([match resultType] == NSTextCheckingTypeLink)
{
NSURL *url = [match URL];
// does some stuff
}
}
Является ли это ошибкой с обнаружением ссылок Apple здесь, где он не может обнаружить ссылки с пробелами, или я делаю что-то неправильно?
Есть ли у кого-нибудь более надежный способ обнаружения ссылок независимо от того, имеют ли они пробелы или специальные символы или что-то в них?
Ответы
Ответ 1
Я получил ответ от Apple за ошибку, которую я написал по этому поводу:
Мы полагаем, что этот вопрос был рассмотрен в последней бета-версии iOS 9. Это предварительное обновление iOS 9.
Пожалуйста, ознакомьтесь с примечаниями к выпуску для полной установки инструкции.
Проконсультируйтесь с этой версией. Если у вас все еще есть проблемы, пожалуйста, предоставлять любые соответствующие журналы или информацию, которые могли бы помочь нам исследовать.
iOS 9 https://developer.apple.com/ios/download/
Я проверю и дам вам знать, исправлено ли это с iOS 9.
Ответ 2
Вы можете разделить строки на куски, используя пробелы, чтобы у вас был массив строк без пробелов. Затем вы можете подавать каждую из этих строк в свой детектор данных.
// 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
}
Другой альтернативой является просмотр этого тега 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
Я нашел очень хакерский способ решить мою проблему. Если кто-то придумает лучшее решение, которое можно применить ко всем URL-адресам, сделайте это.
Потому что я только забочусь о URL-адресах, заканчивающихся на .jpg
, у которых есть эта проблема, я смог найти узкий способ отслеживания этого.
По существу, я разбиваю строку на компоненты, основанные на них, начиная с "http://
в массив. Затем я прохожу через этот массив, который еще раз разыскивает поиск .jpg">
. Счетчик внутреннего массива будет > 1
, когда будет найдена строка .jpg">
. Затем я сохраняю как строку, которую я нахожу, так и строку, которую я исправляю с заменой %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;
}
Ответ 4
Вы можете использовать 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);
}
}
Ответ 5
Попробуйте этот шаблон регулярного выражения: @"<img[^>]+src=(\"|')([^\"']+)(\"|')[^>]*>"
с игнорированием case... Match index = 2 для исходного URL.
regex demo в javascript: (попробуйте для любой помощи)
Демо
Ответ 6
Попробуйте этот фрагмент (я получил регулярное выражение от вашего первого комментатора user3584460):
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
Ответ 7
Вы не должны использовать NSDataDetector с HTML. Он предназначен для разбора обычного текста (вводится пользователем), а не сгенерированных компьютером данных (на самом деле у него много эвристик, чтобы убедиться, что он не обнаруживает генерируемые компьютером вещи, которые, вероятно, не имеют отношения к пользователю).
Если ваша строка - это HTML, вы должны использовать библиотеку разбора HTML. Существует множество наборов с открытым исходным кодом, которые помогут вам в этом. Затем просто возьмите атрибуты href ваших якорей или запустите NSDataDetector на текстовых узлах, чтобы найти вещи, не помеченные, не загрязняя строку тегами.
Ответ 8
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
}