【问题标题】:Strip Non-Alphanumeric Characters from an NSString从 NSString 中去除非字母数字字符
【发布时间】:2009-11-01 04:40:06
【问题描述】:

我正在寻找一种从NSString 中去除非字母数字字符的快速简便的方法。可能是使用NSCharacterSet 的东西,但我很累,似乎没有返回一个只包含字符串中的字母数字字符的字符串。

【问题讨论】:

  • +1 是正确标记为 cocoa 而不是 objective-c 的 5% 的问题之一

标签: cocoa cocoa-touch nsstring nscharacterset


【解决方案1】:

我们可以通过拆分然后加入来做到这一点。组件SeparatedByCharactersInSet 需要 OS X 10.5+:

NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
NSString *strippedReplacement = [[someString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""];

【讨论】:

  • 什么是字母数字字符?例如。德语“元音变音”,如 ä、ö 或 ü 是否会包含在集合中,因此不会被修剪?
  • 要处理重音字符,您需要创建一个 NSMutableCharacterSet,它是 alphanumericCharacterSet 和 nonBaseCharacterSet 的并集,并将其反转
  • trimmedReplacement 具有误导性。在所有 iOS NSString 调用中,trimmed 表示从开始到结束。我可以建议 occurrencesReplacementstrippedReplacement 代替吗?
  • @Erik,将包括变音符号。这使得它无法用于文件名:(
  • @datayeah 不用担心,只需根据pubs.opengroup.org/onlinepubs/9699919799/basedefs/… 更改第一行以反转“便携式文件名字符集”:NSCharacterSet *charactersToRemove = [[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"] invertedSet];
【解决方案2】:

在 Swift 中,componentsJoinedByStringjoin(...) 替换,所以这里它只是用空格替换非字母数字字符。

let charactersToRemove = NSCharacterSet.alphanumericCharacterSet().invertedSet
let strippedReplacement = " ".join(someString.componentsSeparatedByCharactersInSet(charactersToRemove))

对于 Swift2 ...

var enteredByUser = field.text .. or whatever

let unsafeChars = NSCharacterSet.alphanumericCharacterSet().invertedSet

enteredByUser = enteredByUser
         .componentsSeparatedByCharactersInSet(unsafeChars)
         .joinWithSeparator("")

如果您只想删除一个字符,例如删除所有返回...

 enteredByUser = enteredByUser
         .componentsSeparatedByString("\n")
         .joinWithSeparator("")

【讨论】:

    【解决方案3】:

    我最终做的是创建一个 NSCharacterSet 和我发现的 -invertedSet 方法(奇怪的是,多睡一小时对文档阅读能力有什么作用)。这是代码 sn-p,假设 someString 是您要从中删除非字母数字字符的字符串:

    NSCharacterSet *charactersToRemove =
    [[ NSCharacterSet alphanumericCharacterSet ] invertedSet ];
    
    NSString *trimmedReplacement =
    [ someString stringByTrimmingCharactersInSet:charactersToRemove ];
    

    trimmedReplacement 然后将包含someString 的字母数字字符。

    【讨论】:

    • 仅供参考,stringByTrimmingCharactersInSet:仅删除字符串开头和结尾的字符。也许这就是你想要的。
    • 嗯,好点子,肯。我不知道。它仍然可以满足我的需求,但很高兴知道。
    【解决方案4】:

    已接受答案的 Swift 3 版本:

    let unsafeChars = CharacterSet.alphanumerics.inverted
    let myStrippedString = myString.components(separatedBy: unsafeChars).joined(separator: "")
    

    【讨论】:

      【解决方案5】:

      清理类别

      我有一个方法调用 stringByStrippingCharactersInSet:stringByCollapsingWhitespace 可能很方便直接插入。

      @implementation NSString (Cleanup)
      
      - (NSString *)clp_stringByStrippingCharactersInSet:(NSCharacterSet *)set
      {
          return [[self componentsSeparatedByCharactersInSet:set] componentsJoinedByString:@""];
      }
      
      - (NSString *)clp_stringByCollapsingWhitespace
      {
          NSArray *components = [self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
          components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]];
      
          return [components componentsJoinedByString:@" "];
      }
      
      @end
      

      【讨论】:

        【解决方案6】:

        Swift 5,扩展:

        extension String {
        
            /// Will strip all non alpha characters from a string
            public var alpha: String {
                return components(separatedBy: CharacterSet.alphanumerics.inverted).joined()
            }
        }
        

        【讨论】:

          【解决方案7】:

          这是Cameron’s category 的 Swift 版本作为扩展:

          extension String {
          
              func stringByStrippingCharactersInSet(set:NSCharacterSet) -> String
              {
                  return (self.componentsSeparatedByCharactersInSet(set) as NSArray).componentsJoinedByString("")
              }
          
              func stringByCollapsingWhitespace() -> String
              {
                  var components:NSArray = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
                  let predicate = NSPredicate(format: "self <> ''", argumentArray: nil)
                  components = components.filteredArrayUsingPredicate(predicate)
          
                  return components.componentsJoinedByString(" ")
              }
          }
          

          【讨论】:

          • "".join(componentsSeparatedByCharactersInSet(set)) 更好。
          【解决方案8】:

          我认为简单的循环将是更快的执行时间:

          @implementation NSString(MyUtil)
          
          - (NSString*) stripNonNumbers {
              NSMutableString* res = [NSMutableString new];
              //NSCharacterSet *numericSet = [NSCharacterSet decimalDigitCharacterSet];
              for ( int i=0; i < self.length; ++i ) {
                  unichar c = [self characterAtIndex:i];
                  if ( c >= '0' && c <= '9' ) // this looks cleaner, but a bit slower: [numericSet characterIsMember:c])
                      [res appendFormat:@"%c", c];
              }
              return res;
          }
          
          @end
          

          【讨论】:

            【解决方案9】:

            这是比提供的答案更有效的方法

            + (NSString *)alphanumericString:(NSString *)s {
            
                NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
                NSMutableString * ms = [NSMutableString stringWithCapacity:[s length]];
                for (NSInteger i = 0; i < s.length; ++i) {
                    unichar c = [s characterAtIndex:i];
                    if (![charactersToRemove characterIsMember:c]) {
                        [ms appendFormat:@"%c", c];
                    }
                }
                return ms;
            
            }
            

            或作为一个类别

            @implementation NSString (Alphanumeric)
            
            - (NSString *)alphanumericString {
            
                NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
                NSMutableString * ms = [NSMutableString stringWithCapacity:[self length]];
                for (NSInteger i = 0; i < self.length; ++i) {
                    unichar c = [self characterAtIndex:i];
                    if (![charactersToRemove characterIsMember:c]) {
                        [ms appendFormat:@"%c", c];
                    }
                }
                return ms;
            
            }
            
            @end
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-02-27
              • 1970-01-01
              • 2018-10-21
              • 1970-01-01
              • 2011-09-13
              相关资源
              最近更新 更多