【问题标题】:grep with regex for phone number使用正则表达式获取电话号码的 grep
【发布时间】:2011-01-17 04:41:36
【问题描述】:

我想从文件中获取电话号码。我知道数字有不同的形式,我可以处理一个,但不知道如何获得统一的正则表达式。例如

  1. xxx-xxx-xxxx

  2. (xxx)xxx-xxxx

  3. xxx xxx xxxx

  4. xxxxxxxxxx

我只能同时处理1、2和4

grep '[0-9]\{3\}[ -]\?[0-9]\{3\}[ -]\?[0-9]\{4\}' file

是否有任何一个正则表达式可以处理所有这四种形式?

【问题讨论】:

  • 您必须通过交替 (|) 分别处理 2。问题是使用基本的正则表达式无法判断括号是否平衡。
  • 查看 Regexr 以获得正则表达式帮助...gskinner.com/RegExr

标签: regex grep


【解决方案1】:
grep -oE '\(?\<[0-9]{3}[-) ]?[0-9]{3}[ -]?[0-9]{4}\>'

匹配您的所有格式。

\&lt;\&gt; 字边界可防止匹配过长的数字,例如 123-123-123451234-123-1234

【讨论】:

    【解决方案2】:

    +?(1[ -])?((\d{3})[ -]|(\d{3}[ -]?)){2}\d{4}

    适用于:

    123-678-1234

    123 678 1234

    (123)-678-1234

    +1-(123)-678-1234

    1-(123)-678-1234

    1 123 678 1234

    1 (123) 678 1234

    【讨论】:

      【解决方案3】:

      我们可以使用更可能运行良好(但编码繁琐)的 or 条件来逐一验证所有必需的电话号码。

      grep '^[0-9]\{10\}$\|^[0-9]\{3\}[-][0-9]\{3\}[-][0-9]\{4\}$\|^[0-9]\{3\}[ ][0-9]\{3\}[ ][0-9]\{4\}$\|^[(][0-9]\{3\}[)][0-9]\{3\}[-][0-9]\{4\}$' phone_number.txt
      

      返回所有特定格式:

      • 920-702-9999
      • (920)702-9999
      • 920 702 9999
      • 9207029999

      【讨论】:

        【解决方案4】:

        这只是 Alan Moore 解决方案的修改版本。这可以防止某些竞争条件,其中数字的最后一部分中的数字超过四位,或者如果数字的总数超过 10:

        grep '\(\(([0-9]\{3\})\|[0-9]\{3\}\)[ -]\?\)\{2\}[0-9]\{4\} '
        

        说明:

        1. \(([0-9]\{3\})\|[0-9]\{3\}\) 正好匹配三位数字(例如 234) 带或不带括号。 \| 执行“或”运算。
        2. 第一个 \( ... \) 将上述格式组合在一起,然后是 space-no space - ([ -]\?) 就是这样做的。
        3. \{2\} 恰好匹配上述两次出现
        4. [0-9]\{4\} ' 恰好匹配一个 4 位数字后跟 space 的匹配项

        而且它也有点短。在 RHEL 和 Ubuntu 上测试。干杯!!

        【讨论】:

        • 很棒的解释!节省我寻找教程的时间!
        【解决方案5】:

        电话号码通常有四种模式

        1. xxx-xxx-xxxx         grep -o '[0-9]\{3\}\-[0-9]\{3\}\-[0-9]\{4\}'  file.txt
        2. (xxx)xxx-xxxx        grep -o '([0-9]\{3\})[0-9]\{3\}\-[0-9]\{4\}'  file.txt
        3. xxx xxx xxxx         grep -o '[0-9]\{3\}\s[0-9]\{3\}\s[0-9]\{4\}'  file.txt
        4. xxxxxxxxxx           grep -o '[0-9]\{10\}' file.txt
        

        全部

        grep -o '\([0-9]\{3\}\-[0-9]\{3\}\-[0-9]\{4\}\)\|\(([0-9]\{3\})[0-9]\{3\}\-[0-9]\{4\}\)\|\([0-9]\{10\}\)\|\([0-9]\{3\}\s[0-9]\{3\}\s[0-9]\{4\}\)' file.txt
        

        当然,我们可以简化上面的正则表达式,但我们也可以把这个简化留给 grep 本身~

        【讨论】:

          【解决方案6】:

          试试这个:

          ^(\d{10}|((([0-9]{3})\s){2})[0-9]{4}|((([0-9]{3})\-){2})[0-9]{4}|([(][0-9]{3}[)])[0-9]{3}[-][0-9]{4})$

          这仅适用于您上面提到的甲酸盐,例如:

          1. xxxxxxxxxx
          2. xxx xxx xxxx
          3. xxx-xxx-xxxx
          4. (xxx)xxx-xxxx

          【讨论】:

            【解决方案7】:
            grep '\(([0-9]\{3\})\|[0-9]\{3\}\)[ -]\?[0-9]\{3\}[ -]\?[0-9]\{4\}' file
            

            解释:

            ([0-9]\{3\})括号内的三位数字

            \|

            [0-9]\{3\} 三位数不是在括号内

            ...带有分组括号 - \(...\) - 在交替周围,因此无论哪个备选匹配,正则表达式的其余部分都表现相同。

            【讨论】:

            • 这个正则表达式的[小]问题,它还匹配最后一部分超过4位的数字,例如123-123-12345 或超过 10 位数的号码。这:grep '\(\(([0-9]\{3\})\|[0-9]\{3\}\)[ -]\?\)\{2\}[0-9]\{4\} ' 应该可以很好地处理这个问题。请参阅下面的回复以获取解释。干杯!!
            • @MacUsers:好点。 OP 只询问如何让正则表达式匹配它应该匹配的所有内容,我回答了这个问题。让它匹配它不应该匹配的东西会更有趣。
            • 请注意,这里使用的另一个技巧是序列“[ -]\?”这允许匹配空格、连字符或用于分隔电话号码中的数字组的任何其他字符。
            【解决方案8】:
            grep -P '[0-9]{3}-[0-9]{3}-[0-9]{3}|[0-9]{3}\ [0-9]{3}\ [0-9]{3}|[0-9]{9}|\([0-9]{3}\)[0-9]{3}-[0-9]{3}'
            

            【讨论】:

              【解决方案9】:

              我知道了:

              debian:tmp$ cat p.txt
              333-444-5555
              (333)333-6666
              123 456 7890
              1234567890
              debian:tmp$ egrep '\(?[0-9]{3}[ )-]?[0-9]{3}[ -]?[0-9]{4}' p.txt
              333-444-5555
              (333)333-6666
              123 456 7890
              1234567890
              debian:tmp$ egrep --version
              GNU grep 2.5.3
              
              Copyright (C) 1988, 1992-2002, 2004, 2005  Free Software Foundation, Inc.
              This is free software; see the source for copying conditions.  There is NO
              warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
              
              debian:tmp$
              

              【讨论】:

              • 这将匹配(333-444-555 也是。
              【解决方案10】:

              我的第一个想法是,您可能会发现更容易查看您的候选编号是否与 四个中的一个正则表达式匹配。这将更容易开发/调试,尤其是当您将来必须处理其他格式时。

              【讨论】:

                【解决方案11】:

                您可以将您的正则表达式组合在一起使用 OR (|) —— 这样也更具可读性!

                【讨论】:

                • 你能给我举个例子吗?我知道 OR(|) 可能有效,但我不知道如何。
                猜你喜欢
                • 1970-01-01
                • 2014-01-27
                • 2023-03-15
                • 1970-01-01
                • 2017-09-23
                • 2014-02-15
                • 1970-01-01
                相关资源
                最近更新 更多