如何使用正则表达式匹配字符或不匹配

时间:2014-01-12 20:05:10

标签: ruby regex

我正在尝试使用可能或可能没有分隔符的数字块并以标准格式返回它们。以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”不起作用。在这种情况下,我可以使用正则表达式来识别缺少什么吗?

4 个答案:

答案 0 :(得分:38)

这已在评论中分享,但只是为了提供一个完整的答案......

您可以随意使用这些工具:

  • x只匹配x
  • x{a,b}xa次之间匹配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}/

答案 1 :(得分:8)

您是否尝试在数字之间匹配0或1个字符?

\d{3}[^0-9a-zA-Z]{0,1}\d{2}[^0-9a-zA-Z]{0,1}\d{4}

答案 2 :(得分:2)

您当前的正则表达式将允许123-45[6789,更不用说各种Unicode字符和控制字符。在极端情况下:

123
45師6789

被认为是你的正则表达式匹配。

您可以使用反向引用来确保分隔符相同。

/\d{3}([.-]?)\d{2}\1\d{4}/

[.-]?将匹配.-或任何内容(由于可选的?量词)。无论这里匹配的是什么,都将用于通过反向引用确保第二个分隔符相同。

答案 3 :(得分:0)

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

似乎可以做到这一点。