it-swarm.com.de

Regex, um die letzten 4 Zeichen einer Zeichenfolge unbekannter Länge mithilfe von C # beizubehalten

Ich muss einen regulären Ausdruck verwenden, um die letzten 4 Zeichen einer Zeichenfolge zu speichern. Ich kenne die Länge der Zeichenfolge nicht, daher muss ich am Ende beginnen und rückwärts zählen. Das Programm ist in c # geschrieben.

Im Folgenden sind zwei Beispielstrings aufgeführt:

  • 840057
  • 1002945

Ich brauche das Ergebnis (die letzten 4 Zeichen):

  • 0057
  • 2945

Meine ursprüngliche Codezeile verwendete Regex.Replace, aber ich konnte keine reguläre Ausdrücke finden, wie Sie in den Kommentaren unten sehen können.

replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);

Ich habe meinen Code auf Regex.Match umgestellt und der Regex (?s)[0-9]{4}$ hat einwandfrei funktioniert (siehe unten):

replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);

Die Verwendung von Regex.Match unterbricht jedoch andere reguläre Ausdrücke, die ich verwende. Beispielsweise verwende ich ^(.).*, um den ersten Buchstaben eines Namens abzurufen. Dies funktioniert bei Verwendung von Regex.Replace, schlägt jedoch fehl, wenn Regex.Match verwendet wird.

Mein Code ist unten. Beachten Sie, dass die ursprüngliche Zeile mit Regex.Replace auskommentiert ist. 

Warum funktioniert Regex.Match mit einem Ausdruck und Regex.Replace mit einem anderen?

      /// Replaces a wildcard in a string
        /// </summary>
        /// <param name="str">The string for which to replace the wildcards</param>
        /// <param name="row">The DataRow in which the string exists</param>
        /// <param name="wildcard">The wildcard to replace</param>
        /// <returns>The string with the wildcard replaced</returns>
        private static string ReplaceWildcardInString(string str, DataRow row, Wildcard wildcard)
        {
            // If the string is null or empty, return it as is
            if (string.IsNullOrEmpty(str))
                return str;

            // This will hold the replacement value
            var replacementVal = string.Empty;

            // If the replacement column value is not empty
            if (!row.IsDBNullOrNull(wildcard.ReplaceByColumnName))
            {
                // Convert its value to string
                replacementVal = row[wildcard.ReplaceByColumnName].ToString();

                // Apply wildcard regex if given
                if (!string.IsNullOrEmpty(wildcard.Regex) && wildcard.RegexReplaceBy != null)
                    //replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);
                    replacementVal = Regex.Match(replacementVal, wildcard.Regex).Value;
            }

            // Replace all wildcards with the replacement value (case insensitive)
            var wildcardPattern = Regex.Escape(string.Format("%{0}%", wildcard.Name));
            str = Regex.Replace(str, wildcardPattern, replacementVal, RegexOptions.Singleline | RegexOptions.IgnoreCase);

            // Return the new string
            return str;
        }

Vielen Dank, ich schätze die Hilfe.

14
user1226884

Die Regex.Replace-Methode ersetzt alle nicht überlappenden Teilstrings, die einem Muster für reguläre Ausdrücke entsprechen, durch eine angegebene Ersetzung. 

Die Regex.Match-Methode durchsucht die angegebene Eingabezeichenfolge nach dem ersten Auftreten des regulären Ausdrucks.

Wenn Sie also eine Zeichenfolge wie 1002945 haben und am Ende genau 4 Ziffern erhalten möchten, können Sie dies verwenden

var result = Regex.Replace("1002945", @".*([0-9]{4})$", "$1", RegexOptions.Singleline);

oder

var matchResult = Regex.Match("1002945", @"[0-9]{4}$");
if (matchResult.Success) 
{
    Console.WriteLine(matchResult.Value);
}

Beim Ersetzen müssen Sie mit der gesamten Zeichenfolge übereinstimmen, übereinstimmen und capture nur die letzten vier Zeichen, die Ziffern sind, und behaupten, dass der Regex-Index sich am Ende der Zeichenfolge befindet ($). Beachten Sie die Verwendung der Option RegexOptions.Singleline , damit . mit dem Zeilenvorschubzeichen übereinstimmt, für den es standardmäßig nicht passt. Die Ersetzungszeichenfolge sollte $1 sein, der Ersetzungsrückverweis auf die erste Erfassungsgruppe, die die Ziffern erfasst.

Wenn Sie Regex.Match("1002945", @"[0-9]{4}$").Value verwenden, match die 4 Ziffern, denen entweder das Ende der Zeichenfolge oder ein Zeilenvorschub und das Ende der Zeichenfolge folgen (dies ist so, weil $ so übereinstimmt, wenn Sie keine Übereinstimmung zulassen möchten vor einer Newline und einem Ende der Zeichenkette verwenden Sie \z manchor). Wenn die Übereinstimmung ermittelt wurde, können Sie mit matchResult.Success prüfen, ob sie erfolgreich war oder fehlgeschlagen ist. Wenn eine Übereinstimmung gefunden wurde, rufen Sie den matchResult.Value ab. Sie brauchen RegexOptions.Singleline nicht mehr, da im regulären Ausdruck kein . vorhanden ist.

12
.*(?=.{4})$

wird alles bis zu den vier letzten Zeichen der Zeichenfolge entsprechen. Wenn Sie diese Übereinstimmung durch String.Empty ersetzen, bleiben nur diese vier Zeichen erhalten.

Wenn die Zeichenfolge weniger als vier Zeichen enthält, bleiben sie in der Zeichenfolge, da der reguläre Ausdruck überhaupt nicht übereinstimmt, sodass nichts zu ersetzen ist.

8
Tim Pietzcker

Sie brauchen Regex nicht für diesen Zweck.

string MyLast4Characters = MyString.Substring(((MyString.Length >= 4) ? (MyString.Length - 4) : (0)));

Dieser Teil ((MyString.Length >= 4) ? (4) : (0)) wird ausgeführt, um zu überprüfen, ob die ursprüngliche Zeichenfolge länger oder gleich 4 Zeichen ist. Dann werden die letzten 4 Zeichen zurückgegeben, andernfalls die gesamte Zeichenfolge

3
Cid

Wenn dies ein regulärer Ausdruck sein muss, denke ich, möchten Sie: .{4}(?=\s|$)

Aber ich stimme zu, dass Regex hier wahrscheinlich nicht die beste Lösung ist.

Ein Zusammenbruch:

. : any character {4} : exacty four times (?= : followed by \s : white space | : or $ : a line ending ) : end the followed by section

1
Ian Martin

Ich würde die Regex.Match-Methode verwenden.
Es passt nur zu dem, was Sie brauchen. 

Sie können es auf zwei Arten verwenden. 

string str = "asdf 12345";
if (str.Length > 4)
{
    // Abbreviated ..
    Console.WriteLine( "{0}", Regex.Match(str, @"(?s).{5}$").Value );

    // Verbose ...
    Regex rx = new Regex(@"(?s).{5}$");
    str = rx.Match(str).Value;
    Console.WriteLine( "{0}", str );
}
else {} // Do something else

Ausgabe 

12345
12345
0
sln

sie können versuchen und verwenden, ist Reverse() für diesen Zweck 

Z.B:- 

string input = "1002945";
string rev = new string(input.Reverse().ToArray());
string res = null;

Match match = Regex.Match(rev, @"\d{4}");
if (match != null && !String.IsNullOrEmpty(match.Value))
{
   res = new string(match.Value.Reverse().ToArray());
}

ausgabe:- 

2945

Dot.fiddle Probe

0
Lucifer

Ich würde Regex.Match so oft wie möglich mit den passenden Gruppen verwenden:

string str = "Hello :) 1002945";
string pattern = @"(.).*(\d{4})$";
Match match = Regex.Match(str, pattern);
if (match.Success)
{
    string firstChar = match.Groups[1].Value;
    string lastNumber = match.Groups[2].Value;
    Console.WriteLine("First character : " + firstChar);
    Console.WriteLine("Last number : " + lastNumber);
}

Ausgabe :

First character : H
Last number : 2945
0
teikitel

Ich denke mal das ist etwas mit deiner RegexOptions. In meinem Beispiel verwende ich SingleLine mode ((?s)) und mehrzeilige Zeichenfolge:

static void RegexTest()
{
    string str = "i am long string\r\nwith the number 1002945";
    string pattern = @"(?s)[0-9]{4}$"; // or @"(?s).{4}$"
    string num = Regex.Match(str, pattern).Value;
}
0
JohnyL