2013-07-09 8 views
5

Ich versuche, eine Zeichenfolge "Bereinigung" -Funktion schreiben, die nur alphanumerische Zeichen sowie einige andere, wie Unterstreichung, Punkt und das Minuszeichen (Bindestrich) erlaubt.Können Sie eine RegEx erstellen, um unerwünschte Zeichen durch den Unterstrich zu ersetzen?

Momentan verwendet unsere Funktion eine direkte Chariteration der Quellzeichenfolge, aber ich versuche, sie in RegEx zu konvertieren, weil das, was ich gelesen habe, viel sauberer und performanter ist (was mir rückwärts über einen Gerade Iteration, aber ich kann es nicht profilieren, bis ich eine funktionierende RegEx bekomme.)

Das Problem ist zweifach für mich. Eines weiß ich, die folgende regex ...

[a-zA-Z0-9] 

... eine Reihe von alphanumerischen Zeichen entspricht, aber wie kann ich auch den Unterstrich, Periode und die Minuszeichen? Entweichst du sie einfach mit dem "\" - Zeichen und legst sie zwischen die Klammern mit dem Rest?

Zweitens, für jedes Zeichen, das nicht Teil der Übereinstimmung ist (d. H. Andere Interpunktion wie '?') Möchten wir es mit einem Unterstrich ersetzt.

Ich denke, stattdessen auf eine Reihe von gewünschten Zeichen übereinstimmen, passen wir auf ein einzelnes Zeichen, das nicht im gewünschten Bereich ist, dann ersetzen Sie das. Ich denke, die RegEx denn das ist die Karat als erstes Zeichen zwischen den Klammern wie folgt schließen ...

[^a-zA-Z0-9] 

Ist das der richtige Ansatz?

+0

Regex.Replace() Methode ist, was Sie brauchen – terrybozzio

+0

ich dachte, dass, aber bitte sehen meine Frage, oder besser gesagt, zwei Fragen dazu. – MarqueIV

+1

Sie möchten Ihre Zeichenklasse invertieren. dh. '[^ a-zA-Z0-9]', was alles entspricht, was _nicht_ alphanumerisch ist. –

Antwort

5

wohl Dies ist am effizientesten, wenn Sie einen statischen Regex einrichten, der die Zeichen beschreibt, die Sie ersetzen möchten.

public static class StringCleaner 
{  
    public static Regex invalidChars = new Regex(@"[^A-Z0-9._\-]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 

    public static string ReplaceInvalidChars(string input) 
    { 
     return invalidChars.Replace(input, "_"); 
    } 
} 

Wenn Sie jedoch Linie ersetzen nicht die Regex wollen endet und Leerzeichen (wie Leerzeichen und Tabulatoren) werden Sie einen etwas anderen Ausdruck verwenden müssen.

public static Regex invalidChars = new Regex(@"[^A-Z0-9._\-\s]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 

Auch hier sind die Regeln für das, was Sie die wörtliche Charakter entkommen muss übereinstimmen: durch eckige Klammern gekennzeichnet

Innerhalb eines Satzes Sie diese Zeichen entkommen muss -#]\ überall sie auftreten und ^ nur, wenn es erscheint in der ersten Position des Satzes, um die wörtlichen Zeichen zu entsprechen. Außerhalb einer Menge müssen Sie diese Zeichen: .$^|{}[]()+?#, um das Literalzeichen zu entgehen.

finden Sie in der folgenden Dokumentation für weitere Informationen:

+0

Eigentlich will ich es * Ersetzen Sie alle Leerstellen und Zeilenenden (und Zeilenanfänge!). Sie sind keine gültigen Zeichen, also ist Ihre erste korrekt. Korrigieren Sie mich jedoch, wenn ich falsch liege, aber Sie beginnen Ihre literalen Zeichenfolgen mit dem '@' Zeichen , was für mich wie Objective C aussieht, nicht C#. ... oder fehlt mir etwas? – MarqueIV

+0

Mir fehlt was! :) Ich weiß jetzt, dass das Starten einer Zeichenkette in C# grundsätzlich die gesamte Zeichenkette für dich entkommt. Ich mag das! Sie erhalten die akzeptierte Antwort für Ihre Vollständigkeit. Vielen Dank! :) – MarqueIV

+1

Ja, das Starten einer Zeichenfolge mit @ "in C# macht es literal. Hier ist der Teil der Sprachspezifikation, der es erklärt: http://msdn.microsoft.com/en-us/library/aa691090(v=VS. 71) .aspx – JamieSee

3

Wenn Sie versuchen, Zeichen zu entfernen, die Sie nicht wollen, Sie besser gedient Regex.Replace würde:

string cleaned = Regex.Replace(input, "[^a-zA-Z0-9_.]|-", "_"); 

die schließen ‚-‘ Zeichen, das Sie nur die Regex verwenden oder schließen dieser Charakter, obwohl es wahrscheinlich einen Weg gibt, ihn in die Charakterklasse aufzunehmen, entgeht er mir im Moment.

Bearbeiten: Sie müssen nicht wirklich den Bindestrich explizit einfügen, da es sowieso nicht die Klasse entspricht. Das heißt, wenn Sie den Bindestrich durch einen Unterstrich ersetzen möchten, verwenden Sie einfach [^a-zA-Z0-9_.] als Ihre Klasse ... alles, was nicht mit diesen Klassen übereinstimmt, wird ersetzt. Die korrekte Methode zum Einfügen eines Bindestrichs in eine Klasse besteht jedoch darin, sie mit einem umgekehrten Schrägstrich (\-) zu entschlüsseln, oder Sie können sie auf die Liste der Klassen setzen: [^-a-zA-Z0-9_.].

0

Ich denke, es wäre perfekt, die Replace-Methode der Zeichenfolge zu verwenden.

public string StringClean(string source, char replacement, char[] targets) 
{ 
    foreach(char c in targets) 
    { 
    //... 
    } 
} 

(nicht in VS so vielleicht nicht perfekt Code)

+0

Dies ist kein Regex-Code, daher gilt dies nicht für die gestellte Frage. – MarqueIV

0

Wenn Sie alle Zeichen ersetzen müssen, die nicht auf Ihrem beschriebenes Muster mit einem Unterstrich ist dies tun:

string result = Regex.Replace(YourOriginalString, "[^a-zA-Z0-9_.-]", "_"); 
+0

Solltest du am Ende nicht diesen Bindestrich verlassen (oder ist er implizit geflüchtet, weil er am Ende * ist? – MarqueIV

+0

ist implizit, nur für den Fall, und es hat funktioniert. – terrybozzio

Verwandte Themen