141

我有一个NSString这样的:

http://www.

但我想将其转换为:

http%3A%2F%2Fwww.

我怎样才能做到这一点?

4

13 回答 13

333

要转义你想要的字符是一个多一点的工作。

示例代码

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 字符进行编码。

Pre iOS7 使用 Core Foundation
Using Core Foundation With ARC:

NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (__bridge CFStringRef) unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8));

在没有 ARC 的情况下使用 Core Foundation:

NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (CFStringRef)unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8);

注意:-stringByAddingPercentEscapesUsingEncoding不会产生正确的编码,在这种情况下,它不会对返回相同字符串的任何内容进行编码。

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding编码 14 个字符:

`#%^{}[]|\"<> 加上空格字符作为百分比转义。

测试字符串:

" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"  

编码字符串:

"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"  

注意:考虑这组字符是否满足您的需求,如果没有根据需要更改它们。

需要编码的 RFC 3986 字符(添加 %,因为它是编码前缀字符):

"!#$&'()*+,/:;=?@[]%"

一些“未保留字符”被额外编码:

"\n\r \"%-.<>\^_`{|}~"

于 2011-11-10T21:50:50.997 回答
24

它被称为URL 编码。更多在这里

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
           (CFStringRef)self,
           NULL,
           (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
           CFStringConvertNSStringEncodingToEncoding(encoding));
}
于 2011-11-10T21:35:38.627 回答
7

这不是我的解决方案。其他人在stackoverflow中写道,但我忘记了如何。

不知何故,这个解决方案“很好”。它处理变音符号、汉字和几乎所有其他内容。

- (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 而不是 + 来表示空间。就这样。

于 2012-10-17T05:43:11.340 回答
4
 NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );

NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
于 2012-08-30T12:02:11.443 回答
4

这可以在 Objective C ARC 中工作。使用 CFBridgingRelease 将 Core Foundation 样式的对象转换为 Objective-C 对象并将对象的所有权转移给 ARC 。请参阅此处的函数 CFBridgingRelease

+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
                         (kCFAllocatorDefault,
                          (__bridge CFStringRef)string,
                          NULL,
                          CFSTR("!*'();:@&=+$,/?%#[]"),
                          kCFStringEncodingUTF8)
                         );}
于 2016-11-10T09:48:03.810 回答
2

斯威夫特iOS:

仅供参考:我用过这个:

extension String {

    func urlEncode() -> CFString {
        return CFURLCreateStringByAddingPercentEscapes(
            nil,
            self,
            nil,
            "!*'();:@&=+$,/?%#[]",
            CFStringBuiltInEncodings.UTF8.rawValue
        )
    }

}// end extension String
于 2015-04-17T12:18:12.557 回答
2

这是我使用的。请注意,您必须使用该@autoreleasepool功能,否则程序可能会崩溃或锁定 IDE。在我意识到修复之前,我不得不重新启动我的 IDE 三次。看来此代码符合 ARC。

这个问题已经被问过很多次,并且给出了很多答案,但遗憾的是所有选择的答案(以及其他一些建议)都是错误的。

这是我使用的测试字符串: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;
    }
}
于 2016-07-15T07:27:22.620 回答
1
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                             NULL,
                             (CFStringRef)yourString, 
                             NULL, 
                             CFSTR("/:"), 
                             kCFStringEncodingUTF8);

您需要自己释放或自动释放str

于 2011-11-10T21:39:22.940 回答
0

Google 在他们的Google Toolbox for Mac中实现了这一点。所以这是一个很好的地方来展示他们如何做到这一点。另一种选择是包含工具箱并使用它们的实现。

在此处检查实施。(这归结为人们在这里发布的内容)。

于 2016-02-04T15:12:36.410 回答
0

这就是我快速执行此操作的方式。

extension String {
    func encodeURIComponent() -> String {
        return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    }

    func decodeURIComponent() -> String {
        return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
    }
}
于 2016-04-15T22:32:03.867 回答
0

这就是我在 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
}

然后我在定义密码的地方调用了这个函数。

于 2021-03-12T14:40:03.077 回答
-1

//像这样使用NSString实例方法:

+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

请记住,您应该只对您的参数值进行编码或解码,而不是您请求的所有 url。

于 2012-12-09T03:47:46.157 回答
-8
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 );
于 2011-11-11T15:38:00.380 回答