В приложении для iPhone, которое я разрабатываю, есть настройка, в которой вы можете ввести URL-адрес, поскольку из-за формы и функции этот URL-адрес должен быть подтвержден как онлайн, так и офлайн.
Пока мне не удалось найти какой-либо метод для проверки URL-адреса, поэтому вопрос:
Как проверить ввод URL-адреса на iPhone (Objective-C) как в режиме онлайн, так и в автономном режиме?
Ответы:
Благодаря этому посту вы можете избежать использования RegexKit. Вот мое решение (работает для разработки iphone с iOS> 3.0):
- (BOOL) validateUrl: (NSString *) candidate { NSString *urlRegEx = @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"; NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx]; return [urlTest evaluateWithObject:candidate]; }
Если вы хотите проверить в Swift мое решение, приведенное ниже:
func isValidUrl(url: String) -> Bool { let urlRegEx = "^(https?://)?(www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z0-9]{0,61}[a-z0-9]\\.[a-z]{2,6}(/[-\\w@\\+\\.~#\\?&/=%]*)?$" let urlTest = NSPredicate(format:"SELF MATCHES %@", urlRegEx) let result = urlTest.evaluate(with: url) return result }
источник
((http|https)://)?((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
. Это должно сделать http: // или https: // опционально.Почему бы вместо этого просто не положиться
Foundation.framework
?Это делает свою работу и не требует
RegexKit
:NSURL *candidateURL = [NSURL URLWithString:candidate]; // WARNING > "test" is an URL according to RFCs, being just a path // so you still should check scheme and all other NSURL attributes you need if (candidateURL && candidateURL.scheme && candidateURL.host) { // candidate is a well-formed url with: // - a scheme (like http://) // - a host (like stackoverflow.com) }
Согласно документации Apple:
источник
http://www.aol.comhttp://www.nytimes.com
проходит этот тест.NSURL
не возвращает nil, когда я передаю строку @ "# @ # @ $ ##% $ # $ #" или @ "tp: / fdfdfsfdsf". Таким образом, этот метод будет бесполезен для проверки действительных URL-адресов HTTP и т.п.Вместо того, чтобы писать свои собственные регулярные выражения, положитесь на Apple. Я использовал категорию,
NSString
которая используетсяNSDataDetector
для проверки наличия ссылки в строке. Если диапазон ссылки, найденной с помощью,NSDataDetector
равен длине всей строки, то это действительный URL.- (BOOL)isValidURL { NSUInteger length = [self length]; // Empty strings should return NO if (length > 0) { NSError *error = nil; NSDataDetector *dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error]; if (dataDetector && !error) { NSRange range = NSMakeRange(0, length); NSRange notFoundRange = (NSRange){NSNotFound, 0}; NSRange linkRange = [dataDetector rangeOfFirstMatchInString:self options:0 range:range]; if (!NSEqualRanges(notFoundRange, linkRange) && NSEqualRanges(range, linkRange)) { return YES; } } else { NSLog(@"Could not create link data detector: %@ %@", [error localizedDescription], [error userInfo]); } } return NO; }
источник
Мое решение со Swift :
func validateUrl (stringURL : NSString) -> Bool { var urlRegEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+" let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[urlRegEx]) var urlTest = NSPredicate.predicateWithSubstitutionVariables(predicate) return predicate.evaluateWithObject(stringURL) }
Для теста:
var boolean1 = validateUrl("http.s://www.gmail.com") var boolean2 = validateUrl("https:.//gmailcom") var boolean3 = validateUrl("https://gmail.me.") var boolean4 = validateUrl("https://www.gmail.me.com.com.com.com") var boolean6 = validateUrl("http:/./ww-w.wowone.com") var boolean7 = validateUrl("http://.www.wowone") var boolean8 = validateUrl("http://www.wow-one.com") var boolean9 = validateUrl("http://www.wow_one.com") var boolean10 = validateUrl("http://.") var boolean11 = validateUrl("http://") var boolean12 = validateUrl("http://k")
Полученные результаты:
false false false true false false true true false false false
источник
использовать это-
NSString *urlRegEx = @"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
источник
www.google.com/+gplusname
Я решил проблему с помощью RegexKit и создал быстрое регулярное выражение для проверки URL-адреса;
NSString *regexString = @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"; NSString *subjectString = brandLink.text; NSString *matchedString = [subjectString stringByMatching:regexString];
Затем я проверяю, совпадает ли matchedString с subjectString, и если это так, URL-адрес действителен :)
Поправьте меня, если мое регулярное выражение неверно;)
источник
Как ни странно, я действительно не нашел здесь решения, которое было бы очень простым, но все же хорошо справлялось с обработкой
http
/https
ссылками.Имейте в виду, ЭТО НЕ идеальное решение, но оно работало в приведенных ниже случаях. Таким образом, регулярное выражение проверяет, начинается ли URL с символа
http://
илиhttps://
, затем проверяет наличие хотя бы 1 символа, затем проверяет наличие точки, а затем снова проверяет наличие хотя бы 1 символа. Пробелы не допускаются.+ (BOOL)validateLink:(NSString *)link { NSString *regex = @"(?i)(http|https)(:\\/\\/)([^ .]+)(\\.)([^ \n]+)"; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex]; return [predicate evaluateWithObject:link]; }
Протестировано ДЕЙСТВИТЕЛЬНО для этих URL:
@"HTTP://FOO.COM", @"HTTPS://FOO.COM", @"http://foo.com/blah_blah", @"http://foo.com/blah_blah/", @"http://foo.com/blah_blah_(wikipedia)", @"http://foo.com/blah_blah_(wikipedia)_(again)", @"http://www.example.com/wpstyle/?p=364", @"https://www.example.com/foo/?bar=baz&inga=42&quux", @"http://✪df.ws/123", @"http://userid:password@example.com:8080", @"http://userid:password@example.com:8080/", @"http://userid@example.com", @"http://userid@example.com/", @"http://userid@example.com:8080", @"http://userid@example.com:8080/", @"http://userid:password@example.com", @"http://userid:password@example.com/", @"http://142.42.1.1/", @"http://142.42.1.1:8080/", @"http://➡.ws/䨹", @"http://⌘.ws", @"http://⌘.ws/", @"http://foo.com/blah_(wikipedia)#cite-", @"http://foo.com/blah_(wikipedia)_blah#cite-", @"http://foo.com/unicode_(✪)_in_parens", @"http://foo.com/(something)?after=parens", @"http://☺.damowmow.com/", @"http://code.google.com/events/#&product=browser", @"http://j.mp", @"http://foo.bar/?q=Test%20URL-encoded%20stuff", @"http://مثال.إختبار", @"http://例子.测试", @"http://उदाहरण.परीक्षा", @"http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", @"http://1337.net", @"http://a.b-c.de", @"http://223.255.255.254"
Протестировано НЕДЕЙСТВИТЕЛЬНО для этих URL:
@"", @"foo", @"ftp://foo.com", @"ftp://foo.com", @"http://..", @"http://..", @"http://../", @"//", @"///", @"http://##/", @"http://.www.foo.bar./", @"rdar://1234", @"http://foo.bar?q=Spaces should be encoded", @"http:// shouldfail.com", @":// should fail"
Источник URL: https://mathiasbynens.be/demo/url-regex
источник
Вы можете использовать это , если вы не хотите
http
илиhttps
илиwww
NSString *urlRegEx = @"^(http(s)?://)?((www)?\.)?[\w]+\.[\w]+";
пример
- (void) testUrl:(NSString *)urlString{ NSLog(@"%@: %@", ([self isValidUrl:urlString] ? @"VALID" : @"INVALID"), urlString); } - (void)doTestUrls{ [self testUrl:@"google"]; [self testUrl:@"google.de"]; [self testUrl:@"www.google.de"]; [self testUrl:@"http://www.google.de"]; [self testUrl:@"http://google.de"]; }
Выход:
INVALID: google VALID: google.de VALID: www.google.de VALID: http://www.google.de VALID: http://google.de
источник
У решения Lefakir есть одна проблема. Его регулярное выражение не может совпадать с " http://instagram.com/p/4Mz3dTJ-ra/ ". Компонент url имеет комбинированный числовой и буквальный характер. Его регулярное выражение не поддерживает такие URL-адреса.
Вот мое улучшение.
"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*)+)+(/)?(\\?.*)?"
источник
Я нашел самый простой способ сделать это так:
- (BOOL)validateUrl: (NSURL *)candidate { NSURLRequest *req = [NSURLRequest requestWithURL:candidate]; return [NSURLConnection canHandleRequest:req]; }
источник
NSURL
, так что вместо этого можно проверить. И даже в этом случае он использует старый API.Код ниже позволит вам найти действительные URL-адреса
NSPredicate *websitePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"^(((((h|H)(t|T){2}(p|P)s?)|((f|F)(t|T)(p|P)))://(w{3}.)?)|(w{3}.))[A-Za-z0-9]+(.[A-Za-z0-9-:;\?#_]+)+"]; if ([websitePredicate evaluateWithObject:##MY_STRING##]) { printf"Valid" }
для таких URL
источник
Утвержденный ответ неверен. У меня есть URL-адрес со знаком «-», и проверка не выполняется.
источник
Откорректировал ответ Вайбхава для поддержки ссылок G +:
NSString *urlRegEx = @"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w-\\+ ./?%&=]*)?";
источник
Некоторые URL-адреса без / в конце не определяются как правильные в приведенных выше решениях. Так что это может быть полезно.
extension String { func isValidURL() -> Bool{ let length:Int = self.characters.count var err:NSError? var dataDetector:NSDataDetector? = NSDataDetector() do{ dataDetector = try NSDataDetector(types: NSTextCheckingType.Link.rawValue) }catch{ err = error as NSError } if dataDetector != nil{ let range = NSMakeRange(0, length) let notFoundRange = NSRange(location: NSNotFound, length: 0) let linkRange = dataDetector?.rangeOfFirstMatchInString(self, options: NSMatchingOptions.init(rawValue: 0), range: range) if !NSEqualRanges(notFoundRange, linkRange!) && NSEqualRanges(range, linkRange!){ return true } }else{ print("Could not create link data detector: \(err?.localizedDescription): \(err?.userInfo)") } return false } }
источник
Проверка URL в Swift
Детали
Xcode 8.2.1, Swift 3
Код
import Foundation enum URLSchemes: String { case http = "http://", https = "https://", ftp = "ftp://", unknown = "unknown://" static func detectScheme(urlString: String) -> URLSchemes { if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .http) { return .http } if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .https) { return .https } if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .ftp) { return .ftp } return .unknown } static func getAllSchemes(separetedBy separator: String) -> String { return "\(URLSchemes.http.rawValue)\(separator)\(URLSchemes.https.rawValue)\(separator)\(URLSchemes.ftp.rawValue)" } private static func isSchemeCorrect(urlString: String, scheme: URLSchemes) -> Bool { if urlString.replacingOccurrences(of: scheme.rawValue, with: "") == urlString { return false } return true } }
import Foundation extension String { var isUrl: Bool { // for http://regexr.com checking // (?:(?:https?|ftp):\/\/)(?:xn--)?(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[#-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)? let schemes = URLSchemes.getAllSchemes(separetedBy: "|").replacingOccurrences(of: "://", with: "") let regex = "(?:(?:\(schemes)):\\/\\/)(?:xn--)?(?:\\S+(?::\\S*)?@)?(?:(?!10(?:\\.\\d{1,3}){3})(?!127(?:\\.\\d{1,3}){3})(?!169\\.254(?:\\.\\d{1,3}){2})(?!192\\.168(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[#-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?" let regularExpression = try! NSRegularExpression(pattern: regex, options: []) let range = NSRange(location: 0, length: self.characters.count) let matches = regularExpression.matches(in: self, options: [], range: range) for match in matches { if range.location == match.range.location && range.length == match.range.length { return true } } return false } var toURL: URL? { let urlChecker: (String)->(URL?) = { url_string in if url_string.isUrl, let url = URL(string: url_string) { return url } return nil } if !contains(".") { return nil } if let url = urlChecker(self) { return url } let scheme = URLSchemes.detectScheme(urlString: self) if scheme == .unknown { let newEncodedString = URLSchemes.http.rawValue + self if let url = urlChecker(newEncodedString) { return url } } return nil } }
Применение
func tests() { chekUrl(urlString:"http://example.com") chekUrl(urlString:"https://example.com") chekUrl(urlString:"http://example.com/dir/file.php?var=moo") chekUrl(urlString:"http://xn--h1aehhjhg.xn--d1acj3b") chekUrl(urlString:"http://www.example.com/wpstyle/?p=364") chekUrl(urlString:"http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com") chekUrl(urlString:"http://example.com") chekUrl(urlString:"http://xn--d1acpjx3f.xn--p1ai") chekUrl(urlString:"http://xn--74h.damowmow.com/") chekUrl(urlString:"ftp://example.com:129/myfiles") chekUrl(urlString:"ftp://user:pass@site.com:21/file/dir") chekUrl(urlString:"ftp://ftp.example.com:2828/asdah%20asdah.gif") chekUrl(urlString:"http://142.42.1.1:8080/") chekUrl(urlString:"http://142.42.1.1/") chekUrl(urlString:"http://userid:password@example.com:8080") chekUrl(urlString:"http://userid@example.com") chekUrl(urlString:"http://userid@example.com:8080") chekUrl(urlString:"http://foo.com/blah_(wikipedia)#cite-1") chekUrl(urlString:"http://foo.com/(something)?after=parens") print("\n----------------------------------------------\n") chekUrl(urlString:".") chekUrl(urlString:" ") chekUrl(urlString:"") chekUrl(urlString:"-/:;()₽&@.,?!'{}[];'<>+_)(*#^%$") chekUrl(urlString:"localhost") chekUrl(urlString:"yandex.") chekUrl(urlString:"коряга") chekUrl(urlString:"http:///a") chekUrl(urlString:"ftps://foo.bar/") chekUrl(urlString:"rdar://1234") chekUrl(urlString:"h://test") chekUrl(urlString:":// should fail") chekUrl(urlString:"http://-error-.invalid/") chekUrl(urlString:"http://.www.example.com/") } func chekUrl(urlString: String) { var result = "" if urlString.isUrl { result += "url: " } else { result += "not url: " } result += "\"\(urlString)\"" print(result) }
Результат
источник
Цель C
- (BOOL)validateUrlString:(NSString*)urlString { if (!urlString) { return NO; } NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil]; NSRange urlStringRange = NSMakeRange(0, [urlString length]); NSMatchingOptions matchingOptions = 0; if (1 != [linkDetector numberOfMatchesInString:urlString options:matchingOptions range:urlStringRange]) { return NO; } NSTextCheckingResult *checkingResult = [linkDetector firstMatchInString:urlString options:matchingOptions range:urlStringRange]; return checkingResult.resultType == NSTextCheckingTypeLink && NSEqualRanges(checkingResult.range, urlStringRange); }
Надеюсь это поможет!
источник
Вы хотели проверить, является ли введенный пользователем URL-адресом? Это может быть так же просто, как регулярное выражение, например проверка, содержит ли строка
www.
(это способ, которым Yahoo messenger проверяет, является ли статус пользователя ссылкой или нет).Надеюсь, что это поможет.
источник
Эгоистично, я бы предложил использовать
KSURLFormatter
экземпляр как для проверки ввода, так и для преобразования его во что-то, с чемNSURL
можно справиться.источник
Я создал унаследованный класс UITextField, который может обрабатывать все виды проверки с использованием строки регулярного выражения. В этом случае вам просто нужно предоставить им всю строку регулярного выражения по порядку и их сообщение, которое вы хотите показать, когда проверка не удалась. Вы можете проверить мой блог для получения дополнительной информации, это действительно поможет вам
http://dhawaldawar.wordpress.com/2014/06/11/uitextfield-validation-ios/
источник
Расширяя ответ @Anthony на swift, я написал категорию, в
String
которой возвращается необязательныйNSURL
. Возвращаемое значение -nil
еслиString
не может быть подтверждено, что это URL.import Foundation // A private global detector variable which can be reused. private let detector = try! NSDataDetector(types: NSTextCheckingType.Link.rawValue) extension String { func URL() -> NSURL? { let textRange = NSMakeRange(0, self.characters.count) guard let URLResult = detector.firstMatchInString(self, options: [], range: textRange) else { return nil } // This checks that the whole string is the detected URL. In case // you don't have such a requirement, you can remove this code // and return the URL from URLResult. guard NSEqualRanges(URLResult.range, textRange) else { return nil } return NSURL(string: self) } }
источник
func checkValidUrl(_ strUrl: String) -> Bool { let urlRegEx: String = "(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+" let urlTest = NSPredicate(format: "SELF MATCHES %@", urlRegEx) return urlTest.evaluate(with: strUrl) }
источник
Мое решение в Swift 5:
extension String { func isValidUrl() -> Bool { do { let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) // check if the string has link inside return detector.numberOfMatches(in: self, options: [], range: .init( location: 0, length: utf16.count)) > 0 } catch { print("Error during NSDatadetector initialization \(error)" ) } return false } }
источник