美国的邮政编码的规则是 5 个数字或者 5 个数字连上 4 个数字,如 12345 或者 54321-1234 ,如果要匹配所有的邮编,则正确的正则表达式为:
\d{5}-\d{4}|\d{5}
//错误写法
\d{5}|\d{5}-\d{4}
下面的错误写法,只能匹配到 5 位数字及 9 位数字的前 5 位数字的情况,而不能匹配 9 位数字的邮编。
为什么下面那种写法就是错的,如果是9位数的邮编,和上面那个写法有什么不同吗?
美国的邮政编码的规则是 5 个数字或者 5 个数字连上 4 个数字,如 12345 或者 54321-1234 ,如果要匹配所有的邮编,则正确的正则表达式为:
\d{5}-\d{4}|\d{5}
//错误写法
\d{5}|\d{5}-\d{4}
下面的错误写法,只能匹配到 5 位数字及 9 位数字的前 5 位数字的情况,而不能匹配 9 位数字的邮编。
为什么下面那种写法就是错的,如果是9位数的邮编,和上面那个写法有什么不同吗?
因为后四位是可选的,推荐另外一种写法:
\d{5}(-\d{4})?
\d{5}
: 匹配5位的连续数字;(-\d{4})
: 这是一个子表达式
,匹配-
和四位连续数字;?
: 问号表示前面的子表达式最多只允许出现一次。
看了下楼主的问题,主要原因是对或“|”的不理解。另外对如何写正则表达式可能不太理解。
首先,我们看下|为什么不能匹配?
正则表达式: d{5}|d{5}-d{4}
当你使用preg_match来匹配的时候,它获取到第一个匹配成功的时候,就不会继续往下进行,因此你只能得到5位数。
当你使用preg_match_all它会匹配“或”两侧的规则,当给一个字符串“54321-1234”,会先所有的5位数会先被匹配出来,第一个规则后剩下的结果是-1234此时再去匹配右侧的规则显然不符合d{5}-d{4},也就不会成功。
另外看下如何写正则表达式?
假如要匹配一个东西,首先要分析哪些是必须项,哪些是可选项。然后就是丢掉必须项,先考虑可选项该如何写。最后再加上必须项。
比如你的需求,5位数是必然出现的,-1234 这种是可能出现的,所以先写 (-d{4})? 再来加上必须项:
\d{5}(-\d{4})?
ok,你都不需要用或 “|” 。
因为JavaScript正则表达式的分支符号|
是顺序执行的,不是优先匹配原则。
顺序执行
的意思就是只要前面的一种选择匹配成功了,分支后面的情况就不再继续匹配。
优先匹配
的意思就是,即使前面的一种可能性匹配成功了,引擎还要对后面的可能性进行匹配,最后匹配成功的长度最长的那个分支,作为匹配结果。
由于JavaScript正则引擎对分支|
采取的顺序执行
,所以通用的解决方法就是:长度最短的一种可能的分支,放在最后。对于邮编这个案例,要把长度最短的5位邮编的可能性放在最后面。
1 回答4k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
2 回答2.2k 阅读✓ 已解决
2 回答1.3k 阅读✓ 已解决
1 回答1.4k 阅读✓ 已解决
2 回答2.2k 阅读
1 回答569 阅读✓ 已解决
我试了一下