3

在过去的两个小时里,我一直在为此扯头发,不禁觉得有一个我看不到的简单解决方案。我正在尝试处理一个字符串 - 一个门牌号(就像您在街道地址中找到的那样)并将其分成四个组成部分。

字符串可以有四种基本的不同模式

A. a numeric value consisting of one or more digits e.g. 5
B. one or more digits followed by a single alphabetic character e.g. 5A
C. two numeric values consisting of one or more digits and joined by a
   hyphen e.g. 5-6
D. two alphanumeric values (with each consisting of one or more digits 
   followed by a single alphabetic character) split by a hyphen e.g. 5A-6B

字符串应始终以数字字符 (1-9) 开头,但其他所有内容都是可选的

我需要最终得到四个值,如下所示

startnumber - it would be 5 in the example above
startsuffix - it would be A in the example above
endnumber - it would be 6 in the example above
endsuffix - it would be B in the example above

startnumber 和 endnumber 可以是一位或多位数字。开始后缀和结束后缀必须是单个字母字符

我的表单上有一些基本验证,只允许输入 0-9、AZ 和“-”字符

我一直在研究很多 if 语句、is_numerics、strpos 等等,但不禁觉得那里可能有一个更明显的答案,可能使用正则表达式,但我真的很挣扎。任何帮助将不胜感激

4

4 回答 4

4

我认为这个正则表达式应该这样做:

(\d+)([A-Z]?)(?:-(\d+)([A-Z]?))?

捕获组 1 到 4 对应于您列出的四个值。

这也将匹配地址,如5-6B. 正则表达式没有记忆,所以当且仅当第一部分有一个字母时,要求第二部分有一个字母是不可行的,除非您使用 4 个不同的正则表达式的组合来处理每种情况。

使用这个正则表达式,调用代码可以简单地检查捕获组 2 和 4 是否都是空的或都是非空的。

于 2013-08-24T23:23:01.880 回答
1

您可以尝试以下方法(这是在原始 PCRE 中):

([0-9]+)([A-Z])?|([0-9]+)-([0-9]+)|([0-9]+)([A-Z])-([0-9]+)([A-Z])

问题是捕获组会因运行而异。如果您不关心验证特定格式,那么您可以试试这个:

([0-9]+)([A-Z])?(?:-([0-9]+)([A-Z])?)?

在这种情况下,第一个捕获组将保存起始编号,第二个,起始后缀,第三个,结束编号,第四个,结束后缀。与我的第一个示例不同,它不会确认输入实际上与您指定的格式之一匹配(即,它将接受 2D-4 或 2-4D),但如果这不是问题,那么它可能更易于使用。

于 2013-08-24T23:25:14.347 回答
0

It's a hack, but it should work:

(?<startnumber>\d+(?:(?<startsuffix>[A-Z]))?)(?:-(?<endnumber>\d+(?:(?<endsuffix>[A-Z]))?))?
于 2013-08-24T23:31:33.357 回答
0

尝试这个:

(\d+(?:[A-Z])?(?:-\d+(?(2)[A-Z])?)?)
于 2013-08-24T23:22:04.417 回答