我正在尝试匹配模式i2
,3位数字,然后是短划线-
和1到3位数字。
示例数据
i2123-1
i2121-20
i2111-331
i2111
i21111
i2111-1141
应该只匹配
i2123-1
i2121-20
i2111-331
我尝试了这个,但它不匹配某些模式,有些模式匹配得太多。
preg_match_all('/i2\d{3}-\d{3}/', $str, $matches);
答案 0 :(得分:1)
您需要将上一个\d{3}
更改为\d{1,3}
,以便在短划线后接受1到3个数字。但即便如此,你仍然会比你想要的更多,我会在这个具体案例中使用单词边界\b
。
preg_match_all('/\bi2\d{3}-\d{1,3}\b/', $str, $matches);
请参阅live demo
答案 1 :(得分:0)
您只需要使用{m,n}
格式使量词接受更少并使用单词边界:
/i2\d{3}-\d{1,3}\b/
或者,负向前瞻或锚点(如果您不想匹配i2123-123-
):
/i2\d{3}-\d{1,3}(?!.)/
/i2\d{3}-\d{1,3}$/
你可能需要最后一个的多线模式:
preg_match_all('/i2\d{3}-\d{1,3}$/m', $str, $matches);
如果你想绝对确定该模式中没有其他内容,请使用锚点和多线模式(如果你还在一个字符串中测试多行:
preg_match_all('/^i2\d{3}-\d{1,3}$/m', $str, $matches);
答案 2 :(得分:0)
我认为正确的解决方案也需要在模式的开头包含\b
,所以我会使用
preg_match_all('/\bi2\d{3}-\d{1,3}\b/', $str, $matches);
针对此示例输入测试此解决方案和其他已发布的解决方案:
i2123-1
i2121-20
i2111-331
i2111
i21111
i2111-1141
i2123-1
1i2121-20
ai2111-331
请参阅此demo。