Geben Sie nur die Ziffern 0-9 von einem String zurück


69

Ich benötige einen regulären Ausdruck, den ich in VBScript und .NET verwenden kann und der nur die Zahlen zurückgibt, die in einer Zeichenfolge gefunden werden.

Zum Beispiel sollte eine der folgenden "Zeichenfolgen" nur 1231231234 zurückgeben

  • 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

Dies wird in einem E-Mail-Parser verwendet, um Telefonnummern zu finden, die Kunden in der E-Mail angeben können, und um eine Datenbanksuche durchzuführen.

Ich habe möglicherweise einen ähnlichen regulären Ausdruck verpasst, aber ich habe auf regexlib.com gesucht.

[EDIT] - Code hinzugefügt, der von RegexBuddy nach dem Einrichten der Antwort von musicfreak generiert wurde

VBScript-Code

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
Wie gesagt, \ D ist einfacher als ^ \ d.
Matthew Flaschen

Antworten:


13

Ich weiß nicht, ob VBScript eine Art "Ersetzen durch reguläre Ausdrücke" hat, aber wenn ja, könnten Sie so etwas wie diesen Pseudocode tun:

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

Ich kenne VBScript nicht, daher kann ich Ihnen den genauen Code nicht geben, aber dies würde alles entfernen, was keine Zahl ist.

BEARBEITEN: Stellen Sie sicher, dass das globale Flag (das "g" am Ende des regulären Ausdrucks) vorhanden ist, da es sonst nur mit der ersten Nicht-Nummer in Ihrer Zeichenfolge übereinstimmt.


Vielen Dank! Genau das wollte ich tun. Ich wusste, dass es etwas einfach sein musste. Ich verwende RegExBuddy und werde versuchen, es zu testen und dann den VBScript-Code zu veröffentlichen. Ich glaube, VBScript wird einen Ersatz leisten.
Brian Boatright

2
Wenn Sie dies mit .NET-Klassen tun möchten, ist es im Grunde re = Regex ("\ D"); re.Replace ("123 123 1234", ""). Denken Sie daran, Ihre Regex-Objekte zwischenzuspeichern (kompilieren Sie sie nicht jedes Mal, wenn die Methode aufgerufen wird).
Matthew Flaschen

191

In .NET können Sie nur die Ziffern aus der Zeichenfolge extrahieren. So was:

string justNumbers = new String(text.Where(Char.IsDigit).ToArray());

1
ps. Ich weiß, dass ich eine VB-Frage mit C # beantwortet habe, aber da es sich um .NET handelt, habe ich mir gedacht, dass es sich lohnt, die Idee zu veröffentlichen. RegEx scheint für etwas so Einfaches übertrieben.
Matt Hamilton

Ich brauchte tatsächlich VBScript, um es auf einer klassischen ASP-Seite zu verwenden, aber ich freue mich über Ihre Antwort.
Brian Boatright

4
Ich wollte gerade einen Kommentar nach dem Motto "/ Klar /, Regex wäre dafür schneller" veröffentlichen, aber ich habe in Mono einen (unwissenschaftlichen) Benchmark durchgeführt und Linq hat gewonnen (ungefähr die Hälfte der Dauer, die der Regex in Anspruch nahm). :) Also mein Hut ist weg von dir.
Matthew Flaschen

8
+10. Nur ein Kopf hoch für alle da draußen, vergiss using System.Linq;das nicht. Für mich hat VS2010 nur gesagt, dass es keine solche Methode "Wo" für Zeichenfolgen gibt, und IntelliSense würde mir nicht das automatische Hinzufügen für die using-Anweisung geben.
DanM7

Sie müssen auch System.Linq.Expressions verwenden: using System.Linq; using System.Linq.Expressions;
WoodsLink


6

Hinweis: Sie haben hier nur die Hälfte des Problems gelöst.

Für US-Telefonnummern, die "in the wild" eingegeben wurden, haben Sie möglicherweise:

  • Telefonnummern mit oder ohne Präfix "1"
  • Telefonnummern mit oder ohne Vorwahl
  • Telefonnummern mit Nebenstellennummern (wenn Sie blind alle Nicht-Ziffern entfernen, verpassen Sie das "x" oder "Ext." Oder was auch immer auch in der Zeile).
  • Möglicherweise mit mnemonischen Buchstaben codierte Zahlen (800-BUY-THIS oder was auch immer)

Sie müssen Ihrem Code einige Smarts hinzufügen, um die resultierende Ziffernliste an einen einzelnen Standard anzupassen, nach dem Sie tatsächlich in Ihrer Datenbank suchen.

Einige einfache Dinge, die Sie tun können, um dies zu beheben:

  • Überprüfen Sie vor dem Entfernen von Nicht-Ziffern durch RegEx, ob die Zeichenfolge ein "x" enthält. Wenn ja, hacken Sie alles danach ab (behandelt die meisten Versionen des Schreibens einer Nebenstellennummer).

  • Für jede Zahl mit mehr als 10 Ziffern, die mit einer "1" beginnen, hacken Sie die 1 ab. Sie ist nicht Teil der Vorwahl, US-Vorwahlen beginnen im Bereich 2xx.

  • Nehmen Sie für eine Zahl mit mehr als 10 Stellen an, dass der Rest eine Erweiterung ist, und hacken Sie ihn ab.

  • Führen Sie Ihre Datenbanksuche mit einer Mustersuche "endet mit" durch (SELECT * FROM mytable WHERE Telefonnummer LIKE 'blah%'). Dies behandelt Situationen (obwohl mit der Möglichkeit eines Fehlers), in denen die Vorwahl nicht angegeben ist, Ihre Datenbank jedoch die Nummer mit der Vorwahl hat.


1
wahr. Ich habe nach dem regulären Ausdruck etwas hinzugefügt, das die gesamte Zeichenfolge zurückgegeben hat, wenn sie 10-stellig war, oder richtig (Zeichenfolge, 10), wenn sie länger war. Ihr letzter Vorschlag ist gut und etwas, das ich hinzufügen werde. Vielen Dank! +1
Brian Boatright

Tolle Punkte! Ich habe meine Einreichung unten hinzugefügt, um dieses Problem zu lösen.

1

Wie es aussieht, versuchen Sie, eine 10-stellige Telefonnummer zu finden ...

Warum ersetzen Sie nicht zuerst eine Zeichenfolge im Text, um eines der folgenden Zeichen zu entfernen?

<SPACE> , . ( ) - [ ] 

Anschließend können Sie einfach eine Regex-Suche nach einer 10-stelligen Nummer durchführen.

\d{10}

Das ist vorhanden, aber ich wollte, dass es mit einem größeren Bereich von Eingabezeichenfolgen übereinstimmt.
Brian Boatright


0

In Bezug auf die von richardtallent gemachten Punkte behandelt dieser Code die meisten Ihrer Probleme in Bezug auf Nebenstellennummern und den vorangestellten US-Ländercode (+1).

Nicht die eleganteste Lösung, aber ich musste das Problem schnell lösen, damit ich mit dem, was ich tue, weitermachen konnte.

Ich hoffe es hilft jemandem.

 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

Die einfachste Lösung ohne regulären Ausdruck:

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;
   }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.