我的 NSString是这样的:
NSString
http://www.
但我想把它变成:
http%3A%2F%2Fwww.
我怎么能这么做?
这叫做 URL 编码更多的 给你。
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", CFStringConvertNSStringEncodingToEncoding(encoding)); }
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)yourString, NULL, CFSTR("/:"), kCFStringEncodingUTF8);
您将需要释放或自动释放 str自己。
str
要摆脱你想要的角色是一个多一点的工作。
示例代码
IOS7及以上版本:
NSString *unescaped = @"http://www"; NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; NSLog(@"escapedString: %@", escapedString);
NSLog 输出:
字符串: http% 3A% 2F% 2Fwww
下面是有用的 URL 编码字符集:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|} URLHostAllowedCharacterSet "#%/<>?@\^`{|} URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|} URLPathAllowedCharacterSet "#%;<>?[\]^`{|} URLQueryAllowedCharacterSet "#%<>[\]^`{|} URLUserAllowedCharacterSet "#%/:<>?@[\]^`
创建一个综合了以上所有特征的角色集:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
创建 Base64
对于 Base64字符集:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
对于 Swift 3.0:
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
对于 Swift 2.x:
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
注意: stringByAddingPercentEncodingWithAllowedCharacters还将编码需要编码的 UTF-8字符。
stringByAddingPercentEncodingWithAllowedCharacters
Pre iOS7使用核心基础 使用 ARC 的核心基础:
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( NULL, (__bridge CFStringRef) unescaped, NULL, CFSTR("!*'();:@&=+$,/?%#[]\" "), kCFStringEncodingUTF8));
使用没有 ARC 的核心基础:
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)unescaped, NULL, CFSTR("!*'();:@&=+$,/?%#[]\" "), kCFStringEncodingUTF8);
注意: -stringByAddingPercentEscapesUsingEncoding不会产生正确的编码,在这种情况下,它不会编码任何返回相同字符串的内容。
-stringByAddingPercentEscapesUsingEncoding
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding编码14个字符:
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
“ #% ^ {}[] |”< > 加上空格字符作为转义百分比。
TestString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
EncodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
注意: 考虑一下这组字符是否满足您的需要,如果没有根据需要更改它们。
需要编码的 RFC 3986字符(% ,因为它是编码前缀字符) :
“ ! # $& () * + ,/: = ?@[]%”
一些“无保留字符”是另外编码的:
“ n r”%-. < > ^ _‘{ | } ~”
int strLength = 0; NSString *urlStr = @"http://www"; NSLog(@" urlStr : %@", urlStr ); NSMutableString *mutableUrlStr = [urlStr mutableCopy]; NSLog(@" mutableUrlStr : %@", mutableUrlStr ); strLength = [mutableUrlStr length]; [mutableUrlStr replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)]; NSLog(@" mutableUrlStr : %@", mutableUrlStr ); strLength = [mutableUrlStr length]; [mutableUrlStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)]; NSLog(@" mutableUrlStr : %@", mutableUrlStr );
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 ); NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
这不是我的解决方案。有人写了堆栈溢出,但我已经忘了如何。
不知何故,这个解决方案“很好”。它处理发音符号,中文字符,以及几乎任何其他东西。
- (NSString *) URLEncodedString { NSMutableString * output = [NSMutableString string]; const char * source = [self UTF8String]; int sourceLen = strlen(source); for (int i = 0; i < sourceLen; ++i) { const unsigned char thisChar = (const unsigned char)source[i]; if (false && thisChar == ' '){ [output appendString:@"+"]; } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' || (thisChar >= 'a' && thisChar <= 'z') || (thisChar >= 'A' && thisChar <= 'Z') || (thisChar >= '0' && thisChar <= '9')) { [output appendFormat:@"%c", thisChar]; } else { [output appendFormat:@"%%%02X", thisChar]; } } return output; }
如果有人能告诉我这段代码是谁写的,我会很感激的。基本上,他有一些解释,为什么这个编码字符串将完全解码,因为它希望。
我稍微修改了一下他的解决方案。我喜欢用% 20来表示空间,而不是 + 。就这样。
//像下面这样使用 NSString 实例方法:
+ (NSString *)encodeURIComponent:(NSString *)string { NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return s; } + (NSString *)decodeURIComponent:(NSString *)string { NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return s; }
请记住,您应该只对参数值进行编码或解码,而不是对请求的所有 URL 进行编码或解码。
斯威夫特 iOS:
仅供参考: 我用过这个:
extension String { func urlEncode() -> CFString { return CFURLCreateStringByAddingPercentEscapes( nil, self, nil, "!*'();:@&=+$,/?%#[]", CFStringBuiltInEncodings.UTF8.rawValue ) } }// end extension String
谷歌在他们的 面向 Mac 的谷歌工具箱中实现了这一点。所以这是一个很好的地方,他们是如何做到这一点。另一种选择是包含“工具箱”并使用它们的实现。
检查实现 给你。(这可以精确地归结为人们在这里发布了什么)。
我就是这么迅速做到的。
extension String { func encodeURIComponent() -> String { return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! } func decodeURIComponent() -> String { return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding! } }
这是我用的。注意,必须使用 @autoreleasepool特性,否则程序可能会崩溃或锁定 IDE。我不得不重新启动 IDE 三次,直到我意识到这个问题。看起来这个代码是 ARC 兼容的。
@autoreleasepool
这个问题已经被问过很多次了,也给出了很多答案,但遗憾的是,所有被选中的问题(以及其他一些建议)都是错误的。
下面是我使用的测试字符串: This is my 123+ test & test2. Got it?!
This is my 123+ test & test2. Got it?!
下面是我的 Objective C + + 类方法:
static NSString * urlDecode(NSString *stringToDecode) { NSString *result = [stringToDecode stringByReplacingOccurrencesOfString:@"+" withString:@" "]; result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return result; } static NSString * urlEncode(NSString *stringToEncode) { @autoreleasepool { NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)stringToEncode, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8 )); result = [result stringByReplacingOccurrencesOfString:@"%20" withString:@"+"]; return result; } }
这可以在 Objective C ARC 中工作。使用 CFBridgingrelease 将 Core Foundation 风格的对象转换为 Objective-C 对象,并将对象的所有权转移给 ARC。请参阅这里的 功能 CFBridge 释放。
+ (NSString *)encodeUrlString:(NSString *)string { return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes (kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8) );}
这就是我在 Swift 5中所做的:
func formatPassword() -> String { var output = ""; for ch in self { let char = String(ch) switch ch { case " ": output.append("+") break case ".", "-", "_", "~", "a"..."z", "A"..."Z", "0"..."9": output.append(char) break default: print(ch) let unicode = char.unicodeScalars.first?.value ?? 0 let unicodeValue = NSNumber(value: unicode).intValue let hexValue = String(format: "%02X", arguments: [unicodeValue]) output = output.appendingFormat("%%%@", hexValue) } } return output as String }
然后调用定义密码的函数。