2

I need to extract some phone numbers from large strings in rails. These numbers will come in a variety of formats and could have multiple phone numbers in a single string.

Here is an example of the types of formats that occur:

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

What is the most efficient way to extract phone numbers like this that appear within a body of text?

UPDATE: Thanks for the answers. After testing some of them I realise that I should include more examples. Here are some more that don't appear in the list above:

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

6 回答 6

6

我会保持简单:

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

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

需要更多字符:

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

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

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

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

如果电话号码总是以 0 开头:

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

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

在进一步的示例之后添加

\b[\s()\d-]{6,}\d\b
于 2013-07-20T23:45:28.083 回答
4

以下是我的做法:

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"]

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

有很多方法可以格式化电话号码。“电话号码验证的综合正则表达式”是一个很好的想法起点。根据所选答案中的评论:

只需去除输入中的所有非数字字符(“x”除外)

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

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

在测试字符串上使用它会scan捕获上面的所有示例电话号码。一旦你让他们遵循该答案中的下一条建议:

[...] 然后,当您显示时,重新格式化您的心满意足。

于 2013-07-21T03:41:16.093 回答
1

我会用这个

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

于 2013-07-20T23:41:22.287 回答
1

我已经写了这个((\+\d+\s*|00\d+\s*|0\d+\s*)(\(\d+\)\s*|\d+\s*)?(\d{2,10}(\-|\/|\s)*){3,8})\b ,只要数字以+a0或开头,它就可以很好地工作00,这是避免剥离其他非电话数字组所必需的。

于 2015-10-29T08:55:36.610 回答
0

我很惊讶在任何人的答案中都没有看到任何 7。这是一个除了最后一个之外的所有内容:

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

也许你可以去掉()第一个。

于 2013-07-21T11:05:43.427 回答
0

识别电话号码的一般问题非常棘手。但是鉴于您上面的示例,如何:

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

两位或三位数字,可选空格或破折号,三位数字,可选空格或破折号,四位或更多位。

于 2013-07-20T23:43:10.683 回答