从字符串中仅返回数字0-9

80
我需要一个正则表达式,可以在VBScript和.NET中使用,仅返回在字符串中找到的数字。例如,以下任何一个"字符串"都应该只返回1231231234
  • 123 123 1234
  • (123) 123-1234
  • 123-123-1234
  • (123)123-1234
  • 123.123.1234
  • 123 123 1234
  • 1 2 3 1 2 3 1 2 3 4
这将用于电子邮件解析器中,以查找客户在电子邮件中提供的电话号码并进行数据库搜索。 我可能错过了类似的正则表达式,但我已经在regexlib.com上搜索过了。 [编辑] - 添加了由RegexBuddy生成的代码,设置了musicfreak的答案 VBScript代码:
Dim myRegExp, ResultString
Set myRegExp = New RegExp
myRegExp.Global = True
myRegExp.Pattern = "[^\d]"
ResultString = myRegExp.Replace(SubjectString, "")

VB.NET

Dim ResultString As String
Try
      Dim RegexObj As New Regex("[^\d]")
      ResultString = RegexObj.Replace(SubjectString, "")
Catch ex As ArgumentException
      'Syntax error in the regular expression
End Try

C#

string resultString = null;
try {
    Regex regexObj = new Regex(@"[^\d]");
    resultString = regexObj.Replace(subjectString, "");
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

1
就像我之前所说的,\D 比 ^\d 更简单。 - Matthew Flaschen
8个回答

214
在.NET中,您可以从字符串中提取只有数字的部分。可以使用Linq实现如下:
string justNumbers = new String(text.Where(Char.IsDigit).ToArray());

别忘记包含 using System.Linq


2
我知道我用C#回答了一个VB的问题,但由于它是.NET,我觉得把这个想法提出来是值得的。对于这么简单的事情,RegEx似乎有些过头了。 - Matt Hamilton
我实际上需要在经典 ASP 页面中使用 VBScript,但我感谢您的回答。 - Brian Boatright
6
我本来想发表一条评论,大意是“显然,对于这个问题,正则表达式更快”,但我在Mono上进行了一个(不太科学的)基准测试,结果Linq胜出(用时约为正则表达式的一半)。 :) 所以我向你脱帽致敬。 - Matthew Flaschen
10
提醒大家一下,别忘了在这里加入 using System.Linq;。我在VS2010上遇到了一个问题,它说字符串中没有“Where”方法,并且IntelliSense也不会为我自动添加using语句。请注意不要改变原来的意思。 - DanM7
你还需要使用 System.Linq.Expressions:using System.Linq; using System.Linq.Expressions; - WoodsLink
谢谢@MattHamilton - 如果你只想要数字格式,而不是字符串呢? - BenKoshy

20

作为主要.Net解决方案的替代方案,参考自类似问题的回答:

string justNumbers = string.Concat(text.Where(char.IsDigit));

16

我不知道VBScript是否有某种"正则表达式替换"函数,但如果有的话,你可以像下面这样写伪代码:

reg_replace(/\D+/g, '', your_string)

我不懂VBScript,所以无法给你精确的代码,但这将删除所有非数字字符。

编辑:请确保正则表达式具有全局标志(即末尾的"g"),否则它只会匹配字符串中的第一个非数字字符。


谢谢!这正是我想做的。我知道它必须要相当简单。我正在使用RegExBuddy,并将尝试进行测试,然后发布VBScript代码。我相信VBScript会进行替换。 - Brian Boatright
2
如果你想使用.NET类来完成它,基本上是这样的:re = Regex("\D"); re.Replace("123 123 1234", "")。记得缓存你的Regex对象(不要在每次调用方法时编译它们)。 - Matthew Flaschen

7
注意:你只解决了问题的一半。
对于在现实中输入的美国电话号码,可能有以下情况:
- 带或不带“1”前缀的电话号码 - 带或不带区号的电话号码 - 带分机号码的电话号码(如果你盲目地删除所有非数字字符,你会错过行中的“x”或“Ext.”等其他字符)。 - 可能编码为助记字母的号码(如800-BUY-THIS或其他)
你需要在代码中添加一些智能功能,将结果列表中的数字符合一个标准,以便在数据库中进行搜索。
你可以做一些简单的事情来解决这个问题:
- 在正则表达式删除非数字之前,查看字符串中是否有“x”。如果有,截断其后的所有内容(可以处理大多数写扩展号码的版本)。 - 对于任何以“1”开头且具有10位或更多位数字的号码,去掉“1”。它不是区号的一部分,美国区号从2xx范围开始。 - 对于仍超过10位数字的任何号码,假设其余部分是某种扩展,并将其截断。 - 使用“以...结尾”的模式搜索进行数据库搜索(SELECT * FROM mytable WHERE phonenumber LIKE 'blah%')。这将处理没有提供区号但您的数据库中有该号码的情况(尽管可能存在错误的可能性)。

1
我在正则表达式后添加了一些内容,如果字符串为10个数字,则返回整个字符串,如果长度超过10,则返回右侧的10个数字。您上次的建议很好,我会加上的。谢谢!+1 - Brian Boatright
太好了!我在下面添加了我的解决方案来解决这个问题。 - user4914655

1
从外观上看,您正在尝试捕获任何10位数的电话号码....
首先为什么不对文本进行字符串替换,以删除以下任何字符。
<SPACE> , . ( ) - [ ] 

然后,您可以只对10位数字进行正则表达式搜索。
\d{10}

这是现有的代码,但我想让它匹配更广泛的输入字符串。 - Brian Boatright

1

最简单的解决方案,不需要使用正则表达式:

public string DigitsOnly(string s)
   {
     string res = "";
     for (int i = 0; i < s.Length; i++)
     {
       if (Char.IsDigit(s[i]))
        res += s[i];
     }
     return res;
   }

0
关于richardtallent提出的问题,这段代码将处理大多数与分机号码和美国国家代码(+1)前缀有关的问题。
虽然不是最优雅的解决方案,但我必须快速解决问题,以便继续进行我的工作。
希望能对某些人有所帮助。
 Public Shared Function JustNumbers(inputString As String) As String
        Dim outString As String = ""
        Dim nEnds As Integer = -1

        ' Cycle through and test the ASCII character code of each character in the string. Remove everything non-numeric except "x" (in the event an extension is in the string as follows):
        '    331-123-3451 extension 405  becomes 3311233451x405
        '    226-123-4567 ext 405        becomes 2261234567x405
        '    226-123-4567 x 405          becomes 2261234567x405
        For l = 1 To inputString.Length
            Dim tmp As String = Mid(inputString, l, 1)
            If (Asc(tmp) >= 48 And Asc(tmp) <= 57) Then
                outString &= tmp
            ElseIf Asc(tmp.ToLower) = 120
                outString &= tmp
                nEnds = l
            End If
        Next


        ' Remove the leading US country code 1 after doing some validation
        If outString.Length > 0 Then
            If Strings.Left(outString, 1) = "1" Then

                ' If the nEnds flag is still -1, that means no extension was added above, set it to the full length of the string
                ' otherwise, an extension number was detected, and that should be the nEnds (number ends) position.
                If nEnds = -1 Then nEnds = outString.Length

                ' We hit a 10+ digit phone number, this means an area code is prefixed; 
                ' Remove the trailing 1 in case someone put in the US country code
                ' This is technically safe, since there are no US area codes that start with a 1. The start digits are 2-9
                If nEnds > 10 Then
                    outString = Right(outString, outString.Length - 1)
                End If
            End If
        End If

        Debug.Print(inputString + "          : became : " + outString)

        Return outString
    End Function

0

你有没有浏览过 regexlib 上的 电话号码类别?看起来有不少可以满足你的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接