0

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

给出时:

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 正则表达式测试器,但不适用于我的代码。

4

2 回答 2

2

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

但无论如何,lookbehind 并不是这项工作的正确工具。(它几乎从来没有;lookbehind 可能是第二个被滥用最多的正则表达式功能,仅次于.*?.)

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

于 2012-09-25T22:26:50.847 回答
1

两件事情:

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

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

这会给你留下:

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

编辑:

不能有无限的后向断言。改用前瞻(我正在改进你的表达方式):

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

这是一个 Rubular 演示

于 2012-09-25T17:30:23.473 回答