【问题标题】:Regular Expression splitting up of NSString - iOS正则表达式拆分 NSString - iOS
【发布时间】:2013-09-18 22:09:54
【问题描述】:

在 iOS 中使用正则表达式拆分字符串

我已经使用循环解决了这个问题,但是想要一个更清晰的答案,我希望 reg exe guru 可以帮助我。

我的原始字符串可能如下所示

NSString *originalString = @"343 a mr smith needs this work";

NSString *originalStringVerTwo = @"345a mr jones needs this work as well";

NSString *originalStringVerThree = @"345 Mrs Someone";

我需要分成 3 个单独的新字符串:

  • 带有或带有尾随“a”或“b”的数字,如果存在则删除它们之间的空格
  • 人名,可以大写也可以不大写,例如 Mr smith 或 Mrs Jones 等
  • 在此之后,零个或多个单词将出现在最终字符串中

例如

  • 123a先生,这里有一些话
  • 124 b 琼斯夫人 n/p
  • 654 符先生
  • 123 琼斯 n/p
  • 345 n/p

应该会导致以下结果

第 1 行

NSString *one = 123a
NSString *two = mr who
NSString *three = here are some words

第 2 行

NSString *one = 124b // i want the white space removed between number and digit
NSString *two = mrs jones
NSString *three = n/p

第 3 行

NSString *one = 654
NSString *two = Mr Foo
NSString *three = @""

第 4 行

NSString *one = 123
NSString *two = Jones
NSString *three = n/p

第 5 行

NSString *one = 345
NSString *two = n/p
NSString *three = @""

常量将是

  1. 3 位数字,带或不带“a”“b”(123、123 a、123b)
  2. 人名,带或不带称呼(琼斯先生,琼斯)
  3. 人名可能未知 - 因此是“n/p”的确切文本
  4. 名称后面是一个长度为 n 的字符串,以 \n 结尾(这是一组单词\n)。

将空白从 123a 移除到 123a 是理想的,但不是主要要求

【问题讨论】:

  • 您应该使用循环包含您的解决方案。这可能是其他答案的一个很好的起点。
  • 您对名称有严格的格式吗?如果我的名字是“Lady Clöe MᶜDougal”或“Κύριε Δημήτρης Παπαφιλίππου”怎么办?
  • @JamesWebster 我认为它很乱,实际上只会混淆,因此我想废弃它的原因。这些名称是我需要的基本名称,即 Mr jones(可能是大写字母)不会像您展示的示例那样。所以一个称呼和一个姓氏。它也可能是“n/p”(未知名称 - 与 n/p 完全一样)。可能有也可能没有先生/夫人/女士等,可能只是琼斯。名称总是以 3 位数字开头(带或不带 a/b,即 650;605a;605 b)希望有助于增加清晰度。

标签: ios objective-c regex nsstring


【解决方案1】:

这是一个应该可以工作的正则表达式:

       ^             //start of line
       (             //first capture group
            [\d]+    //one or more digits
       )             //end of first capture group 

       (?:           //start of optional non-capturing group
              \s?    //optional whitespace
            (        //second capture group
              [ab]   //character class - a or b
            )        //end of second capture group 
       )?            //end of optional non-capturing group 

       \s            //whitespace

       (             //third capture group
            (?:      //non-capturing group
      Mr|Mrs|Mister  //title alternation
            )         
            \s       //whitespace
            [\w/]+   //1 or more word characters or "/"
       |             //alternation 
            [\w/]+   //1 or more word characters or "/"
       )             //end of third capture group 

       (?:           //start of optional non-capturing group  
            \s       //whitespace
            (        //fourth capture group
            .*       //0 or more of any character
            )        //end of fourth capture group
        )?           //end of optional non-capturing group
       $             //end of line

构建你的正则表达式。我们必须逃脱转义符以将它们保留在 NSString 中:

NSString* regexString =
@"^([\\d]+(?:\\s?[ab])?)\\s((?:Mr|Ms|Mrs|Mister)\\s[\\w/]+|[\\w/]+)(?:\\s(.*))?$";

NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:regexString
                     options:NSRegularExpressionCaseInsensitive
                     error:nil];

制作一个测试数组:

NSArray* testArray = @[
                        @"123a mr who here are some words"
                       ,@"124 b mrs jones n/p"
                       ,@"654 Mr Foo"
                       ,@"123 Jones n/p"
                       ,@"345 n/p"
                       ,@"345"
                       ,@"nothing here"
                       ];

处理测试数组:

for (NSString* string in testArray) {
    NSLog(@" ");
    NSLog(@"input: '%@'",string);

    NSRange range = NSMakeRange(0,string.length);
    if ([regex numberOfMatchesInString:string options:0 range:range] == 1) {
        NSString* body = [regex stringByReplacingMatchesInString:string
                                           options:0
                                             range:range
                                      withTemplate:@"$1\n$2\n$3"];


        NSArray* result = [body componentsSeparatedByString:@"\n"];
        NSString* one = result[0];
        NSString* two = result[1];
        NSString* three = result[2];
        NSLog(@"one:   '%@'",one);
        NSLog(@"two:   '%@'",two);
        NSLog(@"three: '%@'",three);
    } else {
        NSLog(@"no match");
    }
}

输出:

    input: '123a mr who here are some words'
    one:   '123a'
    two:   'mr who'
    three: 'here are some words'

    input: '124 b mrs jones n/p'
    one:   '124b'
    two:   'mrs jones'
    three: 'n/p'

    input: '654 Mr Foo'
    one:   '654'
    two:   'Mr Foo'
    three: ''

    input: '123 Jones n/p'
    one:   '123'
    two:   'Jones'
    three: 'n/p'

    input: '345 n/p'
    one:   '345'
    two:   'n/p'
    three: ''

    input: '345'
    no match

    input: 'nothing here'
    no match

【讨论】:

  • 非常感谢。与我的循环等相比,这是一个多么优雅的解决方案。你是 RegEx 大师!
  • 正则表达式结构的精彩文档。
猜你喜欢
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2013-08-11
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多