我希望匹配以bar
结尾的字符串,例如:foobar
或bar
。这样的正则表达式可以是:/^.*bar$/
。
我还希望排除前缀为u
的字母bar
的字符串,例如,这些字符串不应与正则表达式匹配:ubar
或fooubar
。我试过了/^.*[^u]?bar$/
,但它不起作用。我们怎么能解决这个问题?
答案 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.