如何在正则表达式中排除某些匹配项

时间:2012-11-16 17:18:58

标签: ruby regex

我希望匹配以bar结尾的字符串,例如:foobarbar。这样的正则表达式可以是:/^.*bar$/

我还希望排除前缀为u的字母bar的字符串,例如,这些字符串不应与正则表达式匹配:ubarfooubar。我试过了/^.*[^u]?bar$/,但它不起作用。我们怎么能解决这个问题?

3 个答案:

答案 0 :(得分:4)

只需将整个前缀括在括号中

即可
^(.*[^u])?bar$

如果在u之前至少有一个非bar字符,则只允许更多前面的字符。

或者,如果你的正则表达式引擎支持negative lookbehinds,你可以这样做:

^.*(?<!u)bar$

当此正则表达式到达bar之前的位置时,它会查看其左侧的字符并尝试匹配u。如果不可能,则匹配继续。如果找到u,则lookbehind将使模式失败。如果存在非u字符,并且它是字符串的开头,则此功能都可用。

正如sawa在评论中指出的那样,如果您只是想检查字符串是否以^.*结尾,您甚至不需要bar

(?<!u)bar$

当然,如果您因为某种原因(使用多线模式替换或匹配线路)将整个字符串包含在匹配中,则^.*是必需的。请注意,在第一个正则表达式中,您不能将其遗漏。但是你可以把它改成

([^u]|^)bar$

这也可以避免匹配整个字符串。

答案 1 :(得分:1)

?中的所有内容归入()。这就是说bar之前的整个可选结构(如果存在)不得以u结尾。

例如在JavaScript中:

/^(.*[^u])?bar$/.test("foobar");
// true

/^(.*[^u])?bar$/.test("fooubar");
// false

/^(.*[^u])?bar$/.test("bar");
// true

/^(.*[^u])?bar$/.test("ubar");
// false

答案 2 :(得分:1)

使用lookbehind:

def match_bar? string
  string =~ /(?<!u)bar\z/
end

%w{foobar ubar fooubar}.each do |example|
  puts "#{example} does #{match_bar?(example) ? '' : 'not'} match the regex."
end

输出:

foobar does  match the regex.
ubar does not match the regex.
fooubar does not match the regex.