在Obj-C中使用RegEx:隔离配方成分中的杂货

时间:2012-09-25 16:19:41

标签: objective-c regex nsregularexpression

我正在尝试使用正则表达式来过滤烹饪配方成分中的测量值,准备信息和其他形容词。我想要以下结果:

给出时:

1 cup (3oz) sliced carrots, cut lengthwise

我想:

carrots

使用Mac应用程序“模式”处理正则表达式,以下表达式可以正常工作:

(?<word>[a-zA-Z0-9]+)(?<! cut|cup|sliced|lengthwise|[(0-9)+(oz)?])\b

但是,当我在下面的代码中使用它时,没有匹配 - “matches”数组为空:

NSString *phrase = [NSString stringWithString:@"1 cup (3oz) sliced carrots, cut lengthwise"];

NSRegularExpression *nameExpression = [NSRegularExpression regularExpressionWithPattern:@"(?<word>[a-zA-Z0-9]+)(?<! cut|cup|sliced|lengthwise|[(0-9)+(oz)?])\b" options:NSRegularExpressionSearch error:nil];

NSArray *matches = [nameExpression matchesInString:phrase
                                           options:0
                                             range:NSMakeRange(0, [phrase length])];

我正在设置练习应用程序以使用Obj-C作为目标语言。为什么我没有得到任何比赛?

更新:我发现?<word>是无关紧要的,问题在于?<!字符序列。再一次,表达式

([a-zA-Z0-9]+)(?<! cut|cup|sliced|lengthwise|[(0-9)+(oz)?])\b

适用于我的objective-c正则表达式测试程序,但不适用于我的代码。

2 个答案:

答案 0 :(得分:2)

@ acheong87已经指出了[(0-9)+(oz)?]的问题。与Java一样,NSRegularExpression允许您在lookbehind中使用复杂表达式,只要它可以确定它可以匹配的最大字符数。 [(0-9)+(oz)?]只消耗一个字符,因此lookbehind内的每个替代品都有一个固定的长度。使用正确的版本[0-9]+(?:oz)?,这已不再适用。

但无论如何,看起来不适合这项工作。 (它几乎从来都不是;在.*?之后,lookbehind可能是第二个最被滥用的正则表达式功能。)

如果更正后的正则表达式在测试仪中有效但在代码中无效,请查看单词边界。您的示例代码中有@"\b",可能被解释为退格符。你应该使用的是@"\\b"

答案 1 :(得分:1)

两件事:

(?<word>[a-zA-Z0-9]+)(?<! cut|cup|sliced|lengthwise|[(0-9)+(oz)?])\b 
 ^^^^^^^                                            ^^^^^^^^^^^^^ 
 1                                                  2             
  1. NSRegularExpression Class Reference没有提到“命名捕获组”,这就是它。也许他们不受支持。

  2. 目前,这匹配任何由字符0123456789oz+()?组成的字符串。我不认为这就是你的意思;您可能想要删除外部方括号,并用它们包围0-9

  3. 这会让你:

    ([a-zA-Z0-9]+)(?<! cut|cup|sliced|lengthwise|[0-9]+(oz)?)\b
    

    修改

    不能有无限制的lookbehind断言。改为使用前瞻(我正在改善你的表达方式):

    \b(?!(?:cut|cup|sliced|lengthwise|[0-9]+(?:oz)?)\b)([a-zA-Z0-9]+)
    

    这是a Rubular demo