我想测试一个给定的字符串不属于以下字符串组:22 75。
有人可以告诉为什么PHP的 preg_match("/[^(22|75)]/", "25")
会返回 0 吗?
最奇怪的是,preg_match("/[^(22|76)]/", "25")
按预期返回 1 ...
编辑: 我想我理解错误的原因和性质,而不是如何检查给定的两位数字不匹配20,21,22,23,24,75,76,77,78,79,80 ? 我需要组合一个表达式来检查给定年龄与允许年龄列表(这假定只有两位数字)
我不能使用preg_match()
以外的任何内容(!preg_match()
在我的情况下不可用),我只能使用RegEx模式。
答案 0 :(得分:6)
[^(22|75)]
匹配false,因为它正在寻找以下内容:
|()275
[^(22|76)]
匹配true,因为它正在寻找:
|()276
您将正则表达式包裹在 character class 中(点击了解更多信息)
举一个角色类如何工作的例子,看看这个正则表达式:
[2222222222222221111111199999999999]
此字符类只匹配一个字符,如果它是2
,1
或9
。
要匹配数字25(或22,52和55),您可以使用此字符类:
[25]{2}
这将匹配任意位置包含2
或5
的2位数字。
答案 1 :(得分:3)
字符类是字符(不是字符串)的集合。使用字符类,您告诉正则表达式引擎匹配几个字符中的只有一个。
例如,如果您想匹配a
或e
,则需要撰写[ae]
。如果您想匹配grey
或gray
,则需要撰写gr[ae]y
。
[^(22|75)]
如上所述,字符类与列表中的单个字符匹配。在这里,您使用^
来获取否定的字符类,因此这将匹配提供的列表中不的单个字符。在这种情况下,我们的列表包含以下字符:
( 2 2 | 7 5 )
多个字符只计算一次。所以这实际上变成了:
( 2 | 7 5 )
25
是您要匹配的字符串。正则表达式询问:提供的字符串是否包含不在上面列表中的单个字符? 2
和5
在列表中,所以答案是否即可。这解释了为什么preg_match()
会返回false
(不是false
,0
来确切)。
/[^(22|76)]/
与上述相同。这里唯一的区别是5
已更改为6
。它现在检查以下任何字符的缺失:
( 2 | 7 6 )
提供的字符串仍然与之前相同 - 25
。 字符串是否包含上面列表中没有的任何字符?是的! 包含5
(不在列表中)。这解释了为什么preg_match()
会返回1
。
他们看起来很相似,但他们做了不同的事情。当您想要匹配几个可能的正则表达式中的单个正则表达式时,可以使用轮换。与字符类不同,交替使用正则表达式。一个简单的字符串,比如说foo
也是一个有效的正则表达式。它匹配f
后跟o
,后跟o
。
如果要匹配其中一个包含的字符,请使用字符类。想要在n个字符串之间进行匹配时使用交替。
取消preg_match()
来电并使用正则表达式(22|75)
:
if (!preg_match('/(22|75)/', '25')) {
# code...
}
这是最简单的方法。如果你想使用正则表达式直接实现这一点,那么你可能想要使用环视。
如果这正是您要做的事情,那么您根本不需要正则表达式。利用PHP的内置函数进行字符串操作!它不仅速度更快,而且更具可读性。
在这种情况下,简单的in_array()
就足够了:
if(!in_array('25', array(25,75))) {
# code ...
}
答案 2 :(得分:2)
在正则表达式中,[...]
匹配括号内的任何字符。
更正确:
[^...]
:匹配括号内未列出的任何字符。 (^
:否定)如果您要匹配以[
或]
开头的字符串,请删除22
和76
。
答案 3 :(得分:0)
您的正则表达式询问“字符串是否包含不是(
,2
,7
,5
,|
或{{1}的字符}}?“
这显然不是你想要的。
试试这个:
)
答案 4 :(得分:0)
^ [...]内部是对字符列表的否定。 (22 | 76)
正则表达式多字符否定是一个非常棘手的主题,无法轻易解决。
但你可以反转preg_match函数的返回结果,即:。
if(!preg_match('@22|76@', '25', $matches))
doSomething();