使用正则表达式从字符串中提取电话号码?

时间:2013-07-20 23:35:30

标签: ruby-on-rails ruby regex ruby-on-rails-3

我需要从rails中的大字符串中提取一些电话号码。这些号码将以多种格式出现,并且可以在一个字符串中包含多个电话号码。

以下是发生格式类型的示例:

  • 022 1234567
  • 021 123 2345
  • 0271233211
  • 021-233-9123
  • 09 123 32112
  • 021 2331231或021 321123123

提取出现在文本正文中的电话号码的最有效方法是什么?

更新: 谢谢你的回答。在对其中一些进行测试后,我意识到我应该包含更多示例。以下列表中未显示以下内容:

  • 622 32281
  • 5754321
  • 092213212
  • (09)1234321

6 个答案:

答案 0 :(得分:6)

我会保持简单:

\d{2}[\s\d-]+

两个数字,一个或多个空格,数字或连字符。

需要更多字符:

\d{2}[\s\d-]{5,}

(两个数字和5个或更多的空格,连字符的数量),这将减少错误命中的次数。

这些将包括电话号码后面的额外空格,但结果可能会被修剪。

不过修剪,我会删除连字符和空格,并计算剩余的数字位数,将它们识别为电话号码。

如果电话号码始终以0开头:

0\d[\s\d-]{5,}\d

以数字结束,因此在前面的示例中删除了末尾的空格。

添加以下示例:

\b[\s()\d-]{6,}\d\b

答案 1 :(得分:3)

以下是我如何去做的事情:

LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.".split
STRING = [
  '123 123 1234',
  LOREM_IPSUM.shift(1 + rand(4)),
  '123-123-1234',
  LOREM_IPSUM.shift(1 + rand(4)),
  '12 123 12345',
  LOREM_IPSUM.shift(1 + rand(4)),
  '123 1234567',
  LOREM_IPSUM.shift(1 + rand(4)),
  '123 123456789',
  LOREM_IPSUM.shift(1 + rand(4)),
  '123 12345',
  LOREM_IPSUM.shift(1 + rand(4)),
  '1234567',
  LOREM_IPSUM.shift(1 + rand(4)),
  '1234567890',
  LOREM_IPSUM.shift(1 + rand(4)),
  '123456789',
  LOREM_IPSUM.shift(1 + rand(4)),
  '(12)1234567',
].join(' ')

STRING # => "123 123 1234 Lorem ipsum dolor sit 123-123-1234 amet, consectetur adipisicing 12 123 12345 elit, sed do eiusmod 123 1234567 tempor 123 123456789 incididunt ut 123 12345 labore 1234567 et dolore magna aliqua. 1234567890 Ut enim ad minim 123456789 veniam, (12)1234567"
STRING.scan(/\d+.\d+.\d+/) # => ["123 123 1234", "123-123-1234", "12 123 12345", "123 1234567", "123 123456789", "123 12345", "1234567", "1234567890", "123456789", "12)1234567"]
STRING.scan(/\d+.\d+.\d+/).map{ |s| s.gsub(/\D+/, '') } # => ["1231231234", "1231231234", "1212312345", "1231234567", "123123456789", "12312345", "1234567", "1234567890", "123456789", "121234567"]

我删除了几个重复的格式以简化测试。

有很多方法可以格式化电话号码。 “A comprehensive regex for phone number validation”是思想的良好起点。根据所选答案中的评论:

  

只删除输入上的所有非数字字符(“x”除外)

我认为这是一个合理的起始模式:

/\d+.\d+.\d+/

在测试字符串上使用scan,可以捕获上面的所有示例电话号码。一旦你有了它们,请按照该答案中的下一条建议:

  

[...]然后当你显示时,重新格式化你的心灵内容。

答案 2 :(得分:1)

我会用这个

\b(\d{2}[\s|\-|\d]{2}\d{2}[\s|\d][\s|\-|\d]\d{2,5})\b

答案 3 :(得分:1)

我写了这个((\+\d+\s*|00\d+\s*|0\d+\s*)(\(\d+\)\s*|\d+\s*)?(\d{2,10}(\-|\/|\s)*){3,8})\b 只要数字以+ 000开头,就可以正常运行,这是为了避免剥离其他非电话数字组。

答案 4 :(得分:0)

识别电话号码的一般问题非常棘手。但是根据上面的例子,如何:

/\d{2,3}[\s-]?\d{3}[\s-]?\d{4,}/

两位或三位数,可选空格或短划线,三位数,可选空格或短划线,四位或更多位数。

答案 5 :(得分:0)

我很惊讶在任何人的回答中都没有看到任何7。除了最后一个之外,这里将会有所收获:

/(?=(?:\d[ -]*){7,})([\d -]*)/

也许你可以先删除()