我正在尝试匹配一个模式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);
您需要将您的最后一个更改\d{3}
为\d{1,3}
在破折号后接受 1 到 3 个数字。但即便如此,你仍然会比你想要的更多,我会\b
为这种特定情况使用单词边界。
preg_match_all('/\bi2\d{3}-\d{1,3}\b/', $str, $matches);
观看现场演示
您只需要使用{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);
我相信正确的解决方案也需要包含\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
请参阅此演示。