我需要解析像这样的URL字符串:
&ad_eurl=http://www.youtube.com/video/4bL4FI1Gz6s&hl=it_IT&iv_logging_level=3&ad_flags=0&endscreen_module=http://s.ytimg.com/yt/swfbin/endscreen-vfl6o3XZn.swf&cid=241&cust_gender=1&avg_rating=4.82280613104
我需要将NSString分成像cid=241
和&avg_rating=4.82280613104
这样的符号部分。我一直在使用substringWithRange:
执行此操作,但值以随机顺序返回,因此会混淆它。是否有任何类允许轻松解析,您基本上可以将其转换为NSDictionary,以便能够读取键的值(例如ValueForKey:cid
应该返回241
)。或者只是使用另一种更简单的方法来解析它而不是使用NSMakeRange
来获取子字符串?
答案 0 :(得分:152)
我也在https://stackoverflow.com/a/26406478/215748回答了这个问题。
您可以在URLComponents
中使用queryItems
。
当你获得这个属性的值时,NSURLComponents类会解析查询字符串并返回一个NSURLQueryItem对象数组,每个对象代表一个键值对,按照它们在原始查询字符串中出现的顺序。 / p>
let url = "http://example.com?param1=value1¶m2=param2"
let queryItems = URLComponents(string: url)?.queryItems
let param1 = queryItems?.filter({$0.name == "param1"}).first
print(param1?.value)
使用NSURLComponents
代替URLComponents
。
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
resolvingAgainstBaseURL:NO];
NSArray *queryItems = urlComponents.queryItems;
NSString *param1 = [self valueForKey:@"param1"
fromQueryItems:queryItems];
NSLog(@"%@", param1);
…
- (NSString *)valueForKey:(NSString *)key
fromQueryItems:(NSArray *)queryItems
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", key];
NSURLQueryItem *queryItem = [[queryItems
filteredArrayUsingPredicate:predicate]
firstObject];
return queryItem.value;
}
答案 1 :(得分:115)
编辑(2018年6月):this answer is better。 Apple在iOS 7中添加了NSURLComponents
。
我会创建一个字典,用
获取一个键/值对的数组NSMutableDictionary *queryStringDictionary = [[NSMutableDictionary alloc] init];
NSArray *urlComponents = [urlString componentsSeparatedByString:@"&"];
然后填充字典:
for (NSString *keyValuePair in urlComponents)
{
NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];
[queryStringDictionary setObject:value forKey:key];
}
然后您可以使用
进行查询[queryStringDictionary objectForKey:@"ad_eurl"];
这是未经测试的,你应该做更多的错误测试。
答案 2 :(得分:46)
我有点迟了,但到目前为止提供的答案并没有按照我的要求运作。您可以使用此代码段:
NSMutableDictionary *queryStrings = [[NSMutableDictionary alloc] init];
for (NSString *qs in [url.query componentsSeparatedByString:@"&"]) {
// Get the parameter name
NSString *key = [[qs componentsSeparatedByString:@"="] objectAtIndex:0];
// Get the parameter value
NSString *value = [[qs componentsSeparatedByString:@"="] objectAtIndex:1];
value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "];
value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
queryStrings[key] = value;
}
其中url
是您要解析的网址。您在queryStrings
可变字典中拥有所有已转义的查询字符串。
编辑:Swift版本:
var queryStrings = [String: String]()
if let query = url.query {
for qs in query.componentsSeparatedByString("&") {
// Get the parameter name
let key = qs.componentsSeparatedByString("=")[0]
// Get the parameter value
var value = qs.componentsSeparatedByString("=")[1]
value = value.stringByReplacingOccurrencesOfString("+", withString: " ")
value = value.stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
queryStrings[key] = value
}
}
答案 3 :(得分:8)
对于使用NSURLComponents
的iOS8及更高版本:
+(NSDictionary<NSString *, NSString *> *)queryParametersFromURL:(NSURL *)url {
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSMutableDictionary<NSString *, NSString *> *queryParams = [NSMutableDictionary<NSString *, NSString *> new];
for (NSURLQueryItem *queryItem in [urlComponents queryItems]) {
if (queryItem.value == nil) {
continue;
}
[queryParams setObject:queryItem.value forKey:queryItem.name];
}
return queryParams;
}
对于iOS 8以下:
+(NSDictionary<NSString *, NSString *> *)queryParametersFromURL:(NSURL *)url
NSMutableDictionary<NSString *, NSString *> * parameters = [NSMutableDictionary<NSString *, NSString *> new];
[self enumerateKeyValuePairsFromQueryString:url.query completionblock:^(NSString *key, NSString *value) {
parameters[key] = value;
}];
return parameters.copy;
}
- (void)enumerateKeyValuePairsFromQueryString:(NSString *)queryString completionBlock:(void (^) (NSString *key, NSString *value))block {
if (queryString.length == 0) {
return;
}
NSArray *keyValuePairs = [queryString componentsSeparatedByString:@"&"];
for (NSString *pair in keyValuePairs) {
NSRange range = [pair rangeOfString:@"="];
NSString *key = nil;
NSString *value = nil;
if (range.location == NSNotFound) {
key = pair;
value = @"";
}
else {
key = [pair substringToIndex:range.location];
value = [pair substringFromIndex:(range.location + range.length)];
}
key = [self decodedStringFromString:key];
key = key ?: @"";
value = [self decodedStringFromString:value];
value = value ?: @"";
block(key, value);
}
}
+ (NSString *)decodedStringFromString:(NSString *)string {
NSString *input = shouldDecodePlusSymbols ? [string stringByReplacingOccurrencesOfString:@"+" withString:@" " options:NSLiteralSearch range:NSMakeRange(0, string.length)] : string;
return [input stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
答案 4 :(得分:6)
如果你想在swift中做同样的事情,可以使用扩展名。
extension NSURL {
func queryDictionary() -> [String:String] {
let components = self.query?.componentsSeparatedByString("&")
var dictionary = [String:String]()
for pairs in components ?? [] {
let pair = pairs.componentsSeparatedByString("=")
if pair.count == 2 {
dictionary[pair[0]] = pair[1]
}
}
return dictionary
}
}
答案 5 :(得分:4)
如果你正在使用NSURLComponents
,以下简明的扩展也会有效:
extension NSURLComponents {
func getQueryStringParameter(name: String) -> String? {
return (self.queryItems? as [NSURLQueryItem])
.filter({ (item) in item.name == name }).first?
.value()
}
}
答案 6 :(得分:4)
雨燕5
extension URL {
func queryParams() -> [String:String] {
let queryItems = URLComponents(url: self, resolvingAgainstBaseURL: false)?.queryItems
let queryTuples: [(String, String)] = queryItems?.compactMap{
guard let value = $0.value else { return nil }
return ($0.name, value)
} ?? []
return Dictionary(uniqueKeysWithValues: queryTuples)
}
}
答案 7 :(得分:3)
-(NSArray *)getDataOfQueryString:(NSString *)url{
NSArray *strURLParse = [url componentsSeparatedByString:@"?"];
NSMutableArray *arrQueryStringData = [[NSMutableArray alloc] init];
if ([strURLParse count] < 2) {
return arrQueryStringData;
}
NSArray *arrQueryString = [[strURLParse objectAtIndex:1] componentsSeparatedByString:@"&"];
for (int i=0; i < [arrQueryString count]; i++) {
NSMutableDictionary *dicQueryStringElement = [[NSMutableDictionary alloc]init];
NSArray *arrElement = [[arrQueryString objectAtIndex:i] componentsSeparatedByString:@"="];
if ([arrElement count] == 2) {
[dicQueryStringElement setObject:[arrElement objectAtIndex:1] forKey:[arrElement objectAtIndex:0]];
}
[arrQueryStringData addObject:dicQueryStringElement];
}
return arrQueryStringData;
}
你这个功能只是传递URL,你将获得查询字符串的所有元素。
答案 8 :(得分:3)
此代码有三种情况
1。http://www.youtube.com/watch?v=VWsl7C-y7EI&feature=youtu.be
2。http://youtu.be/lOvcFqQyaDY
3。http://www.youtube.com/watch?v=VWsl7C-y7EI
NSArray *arr = [youtubeurl componentsSeparatedByString:@"v="];
NSString *youtubeID;
if([arr count]>0)
{
if([arr count]==1){
youtubeID= [[youtubeurl componentsSeparatedByString:@"/"] lastObject];
}
else{
NSArray *urlComponents = [[arr objectAtIndex:1] componentsSeparatedByString:@"&"];
youtubeID=[urlComponents objectAtIndex:0];
}
}
答案 9 :(得分:3)
从iOS 8开始,您可以直接在name
上使用属性value
和NSURLQueryItem
。
示例,如何解析URL并获取解析对中的键的特定值。
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:@"someURL" resolvingAgainstBaseURL:false];
NSArray *queryItems = urlComponents.queryItems;
NSMutableArray *someIDs = [NSMutableArray new];
for (NSURLQueryItem *item in queryItems) {
if ([item.name isEqualToString:@"someKey"]) {
[someIDs addObject:item.value];
}
}
NSLog(@"%@", someIDs);
答案 10 :(得分:2)
全功能:
+ (NSString *)getQueryComponentWithName:(NSString *)name fromURL:(NSURL *)url{
NSString *component = nil;
if (url) {
NSString *query = url.query;
NSMutableDictionary *queryStringDictionary = [NSMutableDictionary dictionary];
NSArray *urlComponents = [query componentsSeparatedByString:@"&"];
for (NSString *keyValuePair in urlComponents){
NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];
[queryStringDictionary setObject:value forKey:key];
}
component = [queryStringDictionary objectForKey:name];
}
return component;
}
[self getQueryComponentWithName:@"example" fromURL:[NSURL URLWithString:@"https://google.es/?example=test"]];
答案 11 :(得分:2)
以URL
上的Swift 3扩展名形式对此进行了延迟解决extension URL {
func value(for paramater: String) -> String? {
let queryItems = URLComponents(string: self.absoluteString)?.queryItems
let queryItem = queryItems?.filter({$0.name == paramater}).first
let value = queryItem?.value
return value
}
}
答案 12 :(得分:0)
NSURL中的查询属性将给出查询字符串。然后,您可以使用componentsSeparatedByString
解析查询字符串 NSArray *parameters = [[url query] componentsSeparatedByString:@"&"];
NSMutableDictionary *keyValuePairs = [NSMutableDictionary dictionary];
for (NSString *eachParam in parameters)
{
NSArray *QryParts = [eachParam componentsSeparatedByString:@"="];
if ( [QryParts count] == 2 )
{
keyValuePairs[QryParts[0]] = QryParts[1];
}
else
{
keyValuePairs[QryParts[0]] = QryParts[0];
}
}
NSString * name = [keyValuePairs valueForKey:@"name"];
NSString * username = [keyValuePairs valueForKey:@"username"];
答案 13 :(得分:0)
// response success, so process it
//in IE9 the response is in - responseText
this.templateCache[url] = httpResult.response || httpResult.responseText;
答案 14 :(得分:0)
Swift 2方法:
extension NSURL {
var queryDictionary: [String: String] {
var queryDictionary = [String: String]()
guard let components = NSURLComponents(URL: self, resolvingAgainstBaseURL: false), queryItems = components.queryItems else { return queryDictionary }
queryItems.forEach { queryDictionary[$0.name] = $0.value }
return queryDictionary
}
}
答案 15 :(得分:0)
要获取查询参数作为字典:
extension URL {
var parameters: [String: String] {
var parameters = [String: String]()
if let urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: false),
let queryItems = urlComponents.queryItems {
for queryItem in queryItems where queryItem.value != nil {
parameters[queryItem.name] = queryItem.value
}
}
return parameters
}
}
,如果方便的话,返回Optional。