2 Stimmen

Reguläre Ausdrücke für die Mustersuche mit "Ersetzen" verwenden

Ich habe eine Zeichenfolge in folgendem Format in einer durch Komma getrennten Datei:

someText, "Text with, delimiter", moreText, "Text Again"

Was ich tun muss, ist eine Methode zu erstellen, die durch die Zeichenfolge zu suchen, und wird alle Kommas innerhalb von zitierten Text mit einem Dollarzeichen ($) zu ersetzen.

Nach der Methode wird die Zeichenfolge lauten:

someText, "Text with$ delimiter", moreText, "Text Again"

Ich kenne mich mit RegEx nicht so gut aus, würde aber gerne wissen, wie ich mit regulären Ausdrücken nach einem Muster suchen kann (ein Komma zwischen Anführungszeichen finden) und dieses Komma dann durch das Dollarzeichen ersetzen kann.

3voto

Ben Punkte 5975

Ich persönlich würde Regexe hier vermeiden - vorausgesetzt, es gibt keine verschachtelten Anführungszeichen, ist dies ganz einfach zu schreiben, bis als eine for-Schleife, die ich denke, wird effizienter sein:

var inQuotes = false;
var sb = new StringBuilder(someText.Length);

for (var i = 0; i < someText.Length; ++i)
{
    if (someText[i] == '"')
    {
        inQuotes = !inQuotes;
    }

    if (inQuotes && someText[i] == ',')
    {
        sb.Append('$');
    }
    else
    {
        sb.Append(someText[i]);
    }
}

1voto

eulerfx Punkte 35316

Bei dieser Art von Problemen versagt Regex, machen Sie stattdessen dies:

    var sb = new StringBuilder(str);

    var insideQuotes = false;

    for (var i = 0; i < sb.Length; i++)
    {
        switch (sb[i])
        {
            case '"':
                insideQuotes = !insideQuotes;
                break;
            case ',':
                if (insideQuotes)
                    sb.Replace(',', '$', i, 1);
                break;
        }               
    }

    str = sb.ToString();

Sie können auch eine CSV-Parser um die Zeichenkette zu parsen und sie mit ersetzten Spalten neu zu schreiben.

1voto

Ergwun Punkte 11950

So geht's mit Regex.Replace :

        string output = Regex.Replace(
            input,
            "\".*?\"",
            m => m.ToString().Replace(',', '$'));

Natürlich wird es noch komplizierter, wenn man die escaped doppelten Anführungszeichen ignorieren will. Vor allem, wenn das Escape-Zeichen selbst escaped werden kann.

Angenommen, das Escape-Zeichen ist \ Wenn Sie dann versuchen, die doppelten Anführungszeichen abzugleichen, sollten Sie nur Anführungszeichen abgleichen, denen eine gerade Anzahl von Escape-Zeichen (einschließlich Null) vorausgeht. Das folgende Muster wird dies für Sie tun:

string pattern = @"(?<=((^|[^\\])(\\\\){0,}))"".*?(?<=([^\\](\\\\){0,}))""";

An dieser Stelle sollten Sie vielleicht lieber auf reguläre Ausdrücke verzichten ;)

UPDATE:

Um auf Ihren Kommentar zu antworten: Es ist einfach, den Vorgang für verschiedene Anführungszeichen, Begrenzungszeichen und Platzhalter zu konfigurieren.

        string quote = "\"";
        string delimiter = ",";
        string placeholder = "$";

        string output = Regex.Replace(
            input,
            quote + ".*?" + quote,
            m => m.ToString().Replace(delimiter, placeholder));

0voto

Paul Alexander Punkte 31302

Wenn Sie die Regex-Route gehen möchten, finden Sie hier, wonach Sie suchen:

var result = Regex.Replace( text, "(\"[^,]*),([^,]*\")", "$1$$$2" );

Das Problem mit regex in diesem Fall ist, dass es "this, has, two commas" nicht erwischt.

Sehen Sie, wie es funktioniert unter http://refiddle.com/1ab

-2voto

Cam L Punkte 412

Versuchen Sie es doch einmal: "[ \w ] ,[ \w ] " (einschließlich Anführungszeichen)? Und seien Sie vorsichtig mit der Ersetzung, denn bei der direkten Ersetzung wird die gesamte in Anführungszeichen eingeschlossene Zeichenfolge entfernt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X