正则表达式:当我期望没有匹配时,为什么我在这里得到匹配


Regular Expression: Why am I getting matches here when I expect none?

我有一个正则表达式,它寻找2-3个大写字母,以T结尾,以p, M, C或e开头,在PHP中执行的正则表达式看起来像这样:

<?php
# The string to match against
$DT = 'Sat, 26 Nov 2011 21:04:19 GMT';
# Returns "MT" as a match
preg_match('/[PMCE][A-Z]?T/', $DT, $matches);
# I've also tried this -- returns "M" as a match
preg_match('/P|M|C|E[A-Z]?T/', $DT, $matches);

第二个字符用?标记为可选,但它不应该只能够返回PT、MT、CT、ET或p *T、M*T、C*T、E*T吗?

这个正则表达式不应该匹配上面的字符串,我想?我实际上已经使用了非正则表达式方法,但我想知道我到底做错了什么。"MT"怎么可能与这些表达式中的任何一个匹配呢?

在英语中,我认为这两个字符都是"字符p,M,C或E可能后面跟着任何a - z字符,后面跟着t。

preg_match('/[PMCE][A-Z]?T/', $DT, $matches);

preg_match('/P|M|C|E[A-Z]?T/', $DT, $matches);

这两个都与GMT匹配。如果你想让它是它自己的单词,让它匹配一个空格,像这样:

preg_match('/ [PMCE][A-Z]?T/', $DT, $matches);

P|M|C|E[A-Z]?T表达式转换为P M C E[A-Z]?T,这就是为什么它非常乐意匹配单个"M"的原因。

如果你想让你的第二个正则表达式表现得更像第一个,那么你需要对-ed字符进行分组:(P|M|C|E)[A-Z]?T应该可以做到这一点,但我更喜欢你的原始版本。

第二个字符被标记为可选的?但是它不应该只返回PT、MT、CT、ET或者P*T、M*T、C*T、E*T吗?

当然,但是它返回的是MT,就像你说的,这是一个可能的匹配。我认为您的问题是您不期望preg_match从时区标识符的中间开始匹配尝试。但是在这种情况下,你必须指定so:

preg_match('/'b[PMCE][A-Z]?T/', $DT, $matches);

'b匹配字边界