正则表达式匹配除给定列表之外的所有单词(2)

时间:2012-01-21 15:33:02

标签: regex

我已经阅读了这个正则表达式的热门(28k视图)question。但它对我不起作用。已经找到了更好的正则表达式,但我几乎没有陷入困境。

这是饮料清单:

whisky/gin/nuka-cola/beer/liqueur/abs-inth/tea

并且脚本应该获得所有非软饮料。我找到了很好的正则表达式:

/\b(?!(?:tea|nuka\-cola)\b)[\w\d\-]+\b/

结果是:

1 : whisky
2 : gin
3 : -cola
4 : beer
5 : liqueur
6 : abs-inth

问题在于可乐(第3个结果)。这是因为\ b不喜欢' - '字符。请帮我从列表中删除这个可乐。

2 个答案:

答案 0 :(得分:1)

\b匹配字母数字和非字母数字字符,因此它在nuka-cola中的短划线之前和之后匹配。

因此,您不能将\b用作单词边界锚,但您可以定义自己的。看到您的分隔符为/,只需使用(?<=/|^)作为“单词开头”锚点,将(?=/|$)作为“词尾”锚点:

/(?<=\/|^)(?!(?:tea|nuka\-cola)(?=\/|$))[\w\d\-]+(?=\/|$)/

当然,这假设您正在使用支持lookbehind断言的正则表达式引擎。不幸的是,您没有指定这是哪种语言。例如,JavaScript不支持lookbehinds。

答案 1 :(得分:1)

这个正则表达式可以解决这个问题:

(?>[\w-]+)(?<!tea|nuka-cola)

另一种可能性,如果您确保每个关键字都以正斜杠开头:

/(?!tea|nuka-cola)([\w-]+)

如果你计划只吃两杯不应该出现在你结果中的饮料,那么正则表达式会很快变得难看。在这种情况下,我将有一个正则表达式(或一个简单的循环)匹配列表中的每个单词,并检查匹配的单词是否存在于HashSet中。如果找到匹配项,我不会在结果中包含匹配项。