iOS过滤字符串,限制纯中英文的输入以及汉字转拼音,URL编解码解析等

1. 汉字转拼音,用的系统的API CFStringTransform

///MARK:- 汉字转拼音 是否需要声调
+ (NSString *)hanziTransformPinyin:(NSString *)chinese
                     needVoiceTone:(BOOL)needTone{
    //将NSString装换成NSMutableString
    NSMutableString *pinyin = [chinese mutableCopy];
    //将汉字转换为拼音(带音标)
    if (needTone) {
        CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformMandarinLatin, NO);
    }else{
        //去掉拼音的音标
        CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformMandarinLatin, NO);
        CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformStripCombiningMarks, NO);
    }
    NSString *pinYinStr = pinyin;
    //去除掉首尾的空白字符和换行字符
    pinYinStr = [pinYinStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    //去除掉其它位置的空白字符和换行字符
    pinYinStr = [pinYinStr stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    pinYinStr = [pinYinStr stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    pinYinStr = [pinYinStr stringByReplacingOccurrencesOfString:@" " withString:@""];
//    NSLog(@"去掉空白字符和换行字符的pinyin: %@", pinYinStr);
//    [pinYinStr capitalizedString];//首字母大写
    return pinYinStr;
    
}

2. 纯英文输入,记得之前记录过设置安全键盘可以实现限制输入中文和emoji表情的另类实现,即设置输入框的属性secureTextEntry ,根据键盘的弹出和隐藏动态切换,但是有一点小小的瑕疵(在支持touchID的手机,键盘上方会出现一个小圆圈,就是类似钥匙串的玩意儿,点击之后,验证touchID,然后会看到自己以往在iCloud记录的账户密码.... 安全以及UI方面不是很符合要求),在这里介绍另一种实现方式

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
//指定输入的字符内容
NSString * kLetterVerifyInput = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:kLetterVerifyInput] invertedSet];//与英文取反的集合
        NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];//过滤并拼接起来
        return [string isEqualToString:filtered]; //如果匹配了这个非英文集合 则不会出现在输入框里
}

3. 利用正则过滤字符

//根据正则,过滤特殊字符
- (NSString *)filterCharactor:(NSString *)string withRegex:(NSString *)regexStr{
    NSString *searchText = string;
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexStr options:NSRegularExpressionCaseInsensitive error:&error];
    NSString *result = [regex stringByReplacingMatchesInString:searchText options:NSMatchingReportCompletion range:NSMakeRange(0, searchText.length) withTemplate:@""];
    return result;
}

4. 只能输入中文和只输入英文的处理(标点符号之类的需要自己额外处理一下)

  // 监听处理输入的字符串 把不符合要求的字符串替换掉
   @weakify(self);
    [self.nameTextfield.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
        @strongify(self);
        if(!x.length){
            return ;
        }
        if (self.selectedBtn.tag == 1) {
            //中文
            if (![NSString isChineseCharacter:x]) {
                //过滤非中文字符
                self.nameTextfield.text = [self filterCharactor:x withRegex:@"[^\u4e00-\u9fa5]"];
                return ;
            }
        }else{
            //英文
            NSString *lastStr = [x substringWithRange:NSMakeRange(x.length-1, 1)];
            if (![kLetterVerifyInput containsString:lastStr]) {
                self.nameTextfield.text = [x substringToIndex: x.length - 1];
                return ;
            }
        }
        self.nameTextfield.text = [self.nameTextfield.text removeWhiteSpacesFromString];//移除空格
        if (self.nameTextfield.text.length > 10) {//限制输入的长度
            self.nameTextfield.text = [self.nameTextfield.text substringToIndex:10];
        }
    }];

5. 一些判断纯中文,纯英文,纯数字的正则的方法

//限制中文输入 判断是否中文
+ (BOOL)isChineseCharacter:(NSString*)source {
    //参考了 https://www.jianshu.com/p/b40b3c618fec
    NSString *regex = @"^[\\u4E00-\\u9FEA]+$";
    return ([source rangeOfString:regex options:NSRegularExpressionSearch].length>0);
}
//严格限制英文输入
+ (BOOL)isEnglishCharacter:(NSString*)source {
    NSString *upperRegex = @"^[\\u0041-\\u005A]+$";
    NSString *lowerRegex = @"^[\\u0061-\\u007A]+$";
    BOOL isEnglish = (([source rangeOfString:upperRegex options:NSRegularExpressionSearch].length>0) || ([source rangeOfString:lowerRegex options:NSRegularExpressionSearch].length>0));
    return isEnglish;
}
//判断数字
+ (BOOL)isNumber:(NSString*)source {
    NSString *regex = @"^[\\u0030-\\u0039]+$";
    return ([source rangeOfString:regex options:NSRegularExpressionSearch].length>0);
}

6. URL含有中文或者百分号%,有时候需要根据业务需求编码或者解码,如下:

//以下是添加的NSString的category方法
///MARK:- URL包含中文转码 编码/Encode
- (NSString *)urlEncodeUTF8String{
    if (@available(iOS 9.0, *)) {
        NSString  *newUrlString = [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        return newUrlString;
    }else{
        NSString  *newUrlString = [self stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        return newUrlString;
    }
}
///MARK:- URL包含中文百分号的形式 需要转成中文 解码/Decode
- (NSString *)urlDecodeUTF8String{
    if (@available(iOS 9.0, *)) {
        NSString  *newUrlString = [self stringByRemovingPercentEncoding];
        return newUrlString;
    }else{
        NSString *newUrlString = [self stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        return newUrlString;
    }
}

7. 解析URL的参数 即问好后面的参数键值对,入参是 [url query] 值得注意的是如果urlString含有中文的话,调用[url query]是读不出数据(null), 我认为采用字符串截取比较安全的做法,不用转来转去,我也是这样做的

    // 扫二维码或者什么操作获取一段URLString 即
    if (![URLString containsString:@"?"]) {
          // 没问号 做其他处理
         return ;
      }
      // 有问号去解析参数
      NSInteger location = [URLString rangeOfString:@"?"].location + 1;
     NSString *query = [URLString substringFromIndex: location];
    获取到query 自然就可以获取到参数字典

+ (NSDictionary*)dictionaryFromQuery:(NSString*)query{
    NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&"];//分割键值对
    NSMutableDictionary* pairs = [NSMutableDictionary dictionary];
    NSScanner* scanner = [[NSScanner alloc] initWithString:query];
    while (![scanner isAtEnd]) {
        NSString* pairString = nil;
        [scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];
        [scanner scanCharactersFromSet:delimiterSet intoString:NULL];
        NSArray* kvPair = [pairString componentsSeparatedByString:@"="]; //提取键值
        if (kvPair.count == 2) {//字典一个键 一个值
            NSString* key = [[kvPair objectAtIndex:0] stringByRemovingPercentEncoding];
            NSString* value = [[kvPair objectAtIndex:1] stringByRemovingPercentEncoding];
            [pairs setObject:value forKey:key];
        }
    }
    return [NSDictionary dictionaryWithDictionary:pairs];
}

8. 提取字符串中的数字部分 (局限是会把所有数字都提取出来 可以自己使用逗号分隔,数组切割区分,因为我当时的需求是一串字符串中有且只有一串连续的数字 所有全部提取出来就是了)

- (NSString *)getNumberFromString{
    NSCharacterSet *nonDigitCharacterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    return[[self componentsSeparatedByCharactersInSet:nonDigitCharacterSet] componentsJoinedByString:@""];
}

9. 全角标点符号转半角符号

- (NSString *)full2HalfWithNSString:(NSString *)string {
    if (nil == string || [@"" isEqual:string]) {
        return @"";
    }
    NSMutableString *convertedString = [string mutableCopy];
    CFStringTransform((CFMutableStringRef)convertedString, NULL, kCFStringTransformFullwidthHalfwidth, false);
    NSString *newString = [NSString stringWithString:convertedString];
    newString = [newString stringByReplacingOccurrencesOfString:@" " withString:@" "];
    newString = [newString stringByReplacingOccurrencesOfString:@"‘" withString:@"'"];
    newString = [newString stringByReplacingOccurrencesOfString:@"’" withString:@"'"];
    newString = [newString stringByReplacingOccurrencesOfString:@"`" withString:@"'"];
    newString = [newString stringByReplacingOccurrencesOfString:@"‚" withString:@","];
    newString = [newString stringByReplacingOccurrencesOfString:@"," withString:@","];
    newString = [newString stringByReplacingOccurrencesOfString:@";" withString:@";"];
    newString = [newString stringByReplacingOccurrencesOfString:@"。" withString:@"."];
    newString = [newString stringByReplacingOccurrencesOfString:@"?" withString:@"?"];
    newString = [newString stringByReplacingOccurrencesOfString:@"!" withString:@"!"];
    newString = [newString stringByReplacingOccurrencesOfString:@"--" withString:@"—"];
    return newString;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355