我正在尝试获取一组可能有也可能没有分隔符的数字,并以标准格式返回它们。 以SSN为例:
ex1="An example 123-45-6789"
ex2="123.45.6789 some more things"
ex3="123456789 thank you Ruby may I have another"
应该全部进入返回"123-45-6789"的方法 基本上,除了数字或字母之外的任何内容(包括任何内容)都应该返回 XXX-XX-XXXX 格式的 SSN。难倒的部分是正则表达式识别什么都不可能的一种方式。
到目前为止,我在识别我的 ssn 方面所拥有的:
def format_ssns(string)
string.scan(/d{3}[^0-9a-zA-Z]{1}d{2}[^0-9a-zA-Z]{1}d{4}/).to_a
end
它似乎适用于我所期望的一切,除非什么都没有。 "123456789"不起作用。在这种情况下,我可以使用正则表达式来识别缺少任何东西吗?
这已经在评论中分享过了,但只是为了提供一个完整的答案......
您可以使用以下工具:
-
x
匹配x
恰好一次 -
x{a,b}
匹配x
在a
和b
时间之间 -
x{a,}
匹配至少x
a
次 -
x{,b}
匹配x
最多(最多)b
次 -
x*
匹配x
零次或更多次(与x{0,}
相同) -
x+
匹配x
一次或多次(与x{1,}
相同) -
x?
匹配x
零次或一次(与x{0,1}
相同)
所以你想使用最后一个,因为它正是你要找的(零次或一次)。
/d{3}[^0-9a-zA-Z]?d{2}[^0-9a-zA-Z]?d{4}/
您是否尝试过在数字之间匹配 0 或 1 个字符?
d{3}[^0-9a-zA-Z]{0,1}d{2}[^0-9a-zA-Z]{0,1}d{4}
您当前的正则表达式将允许123-45[6789
,更不用说各种Unicode字符和控制字符了。在极端情况下:
123
45師6789
被视为与您的正则表达式匹配。
您可以使用反向引用来确保分隔符相同。
/d{3}([.-]?)d{2}1d{4}/
[.-]?
将匹配.
、-
或什么都不匹配(由于可选的?
量词)。此处匹配的任何分隔符都将用于通过反向引用确保第二个分隔符相同。
Whelp...看起来我刚刚找到了自己的答案,但任何改进的线索都会有所帮助。
def format_ssns(string)
string.scan(/d{3}[^0-9a-zA-Z]{0,1}d{2}[^0-9a-zA-Z]{1}d{4}/).to_a
end
似乎可以解决问题。