Holen Sie sich Teilzeichenfolge - alles vor bestimmten Zeichen


124

Ich versuche herauszufinden, wie ich am besten alles vor das Zeichen in einer Zeichenfolge bringen kann. Einige Beispielzeichenfolgen finden Sie unten. Die Länge der Zeichenfolge vor - variiert und kann beliebig lang sein

223232-1.jpg
443-2.jpg
34443553-5.jpg

Ich brauche also den Wert, der vom Startindex von 0 bis kurz vor - reicht. Die Teilzeichenfolgen würden sich also als 223232, 443 und 34443553 herausstellen

Antworten:


144

.Net Fiddle Beispiel

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("223232-1.jpg".GetUntilOrEmpty());
        Console.WriteLine("443-2.jpg".GetUntilOrEmpty());
        Console.WriteLine("34443553-5.jpg".GetUntilOrEmpty());

        Console.ReadKey();
    }
}

static class Helper
{
    public static string GetUntilOrEmpty(this string text, string stopAt = "-")
    {
        if (!String.IsNullOrWhiteSpace(text))
        {
            int charLocation = text.IndexOf(stopAt, StringComparison.Ordinal);

            if (charLocation > 0)
            {
                return text.Substring(0, charLocation);
            }
        }

        return String.Empty;
    }
}

Ergebnisse:

223232
443
34443553
344

34

2
Bitte tun Sie ihnen einen Gefallen und fügen Sie auch eine Fehlerprüfung hinzu, vorausgesetzt, er plant, daraus eine Funktion zu machen :)
Josh

Vielen Dank, ich war nah dran, war aber neugierig, ob jemand eine andere Möglichkeit hatte als diese Kombination. Aber ja das funktioniert super und ist immer noch ziemlich kurz.
PositiveGuy

14
Wenn Sie einen string result = source.Substring(0, Math.Max(source.IndexOf('-'), 0))
Einzeiler

2
Anstelle von s.Substring(0, n)kann man verwenden, s.Remove(n)wenn bekannt ist (wie hier), dass die Länge der Zeichenfolge sstrikt überschreitet n.
Jeppe Stig Nielsen

@LukeH Wenn IndexOf in Ihrem Beispiel -1 zurückgibt, wird eine leere Zeichenfolge zurückgegeben, nicht wahr?
Crush

124

Verwenden Sie die Split- Funktion.

static void Main(string[] args)
{
    string s = "223232-1.jpg";
    Console.WriteLine(s.Split('-')[0]);
    s = "443-2.jpg";
    Console.WriteLine(s.Split('-')[0]);
    s = "34443553-5.jpg";
    Console.WriteLine(s.Split('-')[0]);

Console.ReadKey();
}

Wenn Ihre Zeichenfolge keine hat, erhalten -Sie die gesamte Zeichenfolge.


4
Und wenn Sie mehr als einen Bindestrich haben, erhalten Sie mehrere Elemente in Ihrem Array.
James Dunne

2
In der Tat, James, also wäre dies nur eine Lösung, wenn Sie nur einen einzigen Bindestrich erwarten würden. Ich nehme an, Sie könnten Linq-Methoden wie Überspringen und Aggregieren verwenden, um das zu erhalten, was Sie wollten, aber dann haben Sie mehr Code als die bereits vorgeschlagenen Methoden. Es hängt alles davon ab, wie viel Sie über die eingehenden Daten wissen.
Dominic Cronin

7
Und ein paar Jahre später habe ich gerade gemerkt, dass ich zu schnell war, um James 'Standpunkt zuzugeben. In der Frage wird gefragt, wie die Zeichenfolge vor einem bestimmten Zeichen gefunden werden soll. Weitere Instanzen dieses Charakters sind daher irrelevant, und [0] zu nehmen würde "einfach funktionieren". Natürlich hängt es immer noch davon ab, wie sehr wir den eingehenden Daten vertrauen. Was ist, wenn es überhaupt kein '-' gibt?
Dominic Cronin

1
Ich denke, @ JamesDunne-Punkt war, dass Sie durch Aufteilen in ein Array eine Reihe unnötiger Zeichenfolgen erstellen - unnötigen Müll.
Crush

1
Ich würde mir keine Sorgen um "unnötigen Müll" machen. Auf diese Weise erstellte zusätzliche Zeichenfolgen wären sofort nicht erreichbar und würden daher in Generation 0 gesammelt, was in der Tat einen äußerst geringen Overhead darstellt. Das Garbage Collector-Design soll ausdrücklich ermöglichen, dass eine große Anzahl kurzlebiger Gegenstände nahezu ohne Kosten verwendet werden kann.
Dominic Cronin

65
String str = "223232-1.jpg"
int index = str.IndexOf('-');
if(index > 0) {
    return str.Substring(0, index)
}

upvote, weil ich den Index des Trennzeichens kennen muss
Piero Alberto

3
Dies ist tatsächlich die gleiche Antwort wie Fredou (derzeit die beste Antwort), außer dass der Fall, in dem keine Übereinstimmung gefunden wird, nicht behandelt wird.
Dominic Cronin

7

Seit Beginn dieses Threads haben sich die Dinge etwas weiterentwickelt.

Jetzt könnten Sie verwenden

string.Concat(s.TakeWhile((c) => c != '-'));

Wie lässt sich die Leistung mit der offensichtlichen Kombination aus IndexOf und Teilstring vergleichen? Ich gehe davon aus, dass jedes Zeichen an einen StringBuilder angehängt wird und am Ende eine Zeichenfolge erstellt wird. Es sind auch ein paar Funktionsaufrufe eingemischt. Wäre schön gewesen, wenn Substring einfach -1 als "Längen" -Argument nehmen könnte, was "Ende der Zeichenfolge" bedeutet.
Crush

1
Es ist schlimmer für die Effizienz. Wie Sie sagen, wird ein String-Builder verwendet, und nachdem der Code überprüft wurde, wird für jedes Zeichen anscheinend ToString aufgerufen. Es ist klarer, wenn Sie nach mehr als einem Charakter suchen, da Sie das Lambda leicht umschreiben können.
Anthony Wieser

4

Eine Möglichkeit, dies zu tun, besteht darin, String.Substringzusammen mit String.IndexOf:

int index = str.IndexOf('-');
string sub;
if (index >= 0)
{
    sub = str.Substring(0, index);
}
else
{
    sub = ... // handle strings without the dash
}

Geben Sie ab Position 0 den gesamten Text bis zum Bindestrich zurück, schließen Sie ihn jedoch nicht ein.


Wenn index <= 0 ist, sollten Sie nur string.empty zurückgeben.
Keine Rückerstattung Keine Rückgabe

5
@NRNR: wenn du es sagst. Das OP kennt die Geschäftsanforderungen, nicht Sie oder ich.
Michael Petrotta

0

Aufbauend auf der Antwort von BrainCore:

    int index = 0;   
    str = "223232-1.jpg";

    //Assuming we trust str isn't null 
    if (str.Contains('-') == "true")
    {
      int index = str.IndexOf('-');
    }

    if(index > 0) {
        return str.Substring(0, index);
    }
    else {
       return str;
    }

0

Sie können zu diesem Zweck reguläre Ausdrücke verwenden. Es ist jedoch ratsam, zusätzliche Ausnahmen zu vermeiden, wenn die Eingabezeichenfolge nicht mit dem regulären Ausdruck übereinstimmt.

Erstens, um zusätzliche Kopfschmerzen beim Entkommen in das Regex-Muster zu vermeiden, könnten wir einfach die Funktion für diesen Zweck verwenden:

String reStrEnding = Regex.Escape("-");

Ich weiß, dass dies nichts bewirkt - da "-" dasselbe ist wie Regex.Escape("=") == "=", aber es wird zum Beispiel einen Unterschied machen, wenn Charakter ist@"\" .

Dann müssen wir vom Betteln des Strings zum Ende des Strings passen, oder alternativ, wenn das Ende nicht gefunden wird - dann nichts übereinstimmen. (Leerer String)

Regex re = new Regex("^(.*?)" + reStrEnding);

Wenn Ihre Anwendung leistungskritisch ist - wenn nicht, separate Zeile für neuen Regex -, können Sie alles in einer Zeile haben.

Und schließlich gegen String stimmen und passendes Muster extrahieren:

String matched = re.Match(str).Groups[1].ToString();

Danach können Sie entweder eine separate Funktion schreiben, wie dies in einer anderen Antwort der Fall war, oder eine Inline-Lambda-Funktion schreiben. Ich habe jetzt mit beiden Notationen geschrieben - Inline-Lambda-Funktion (erlaubt keine Standardparameter) oder separaten Funktionsaufruf.

using System;
using System.Text.RegularExpressions;

static class Helper
{
    public static string GetUntilOrEmpty(this string text, string stopAt = "-")
    {
        return new Regex("^(.*?)" + Regex.Escape(stopAt)).Match(text).Groups[1].Value;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Regex re = new Regex("^(.*?)-");
        Func<String, String> untilSlash = (s) => { return re.Match(s).Groups[1].ToString(); };

        Console.WriteLine(untilSlash("223232-1.jpg"));
        Console.WriteLine(untilSlash("443-2.jpg"));
        Console.WriteLine(untilSlash("34443553-5.jpg"));
        Console.WriteLine(untilSlash("noEnding(will result in empty string)"));
        Console.WriteLine(untilSlash(""));
        // Throws exception: Console.WriteLine(untilSlash(null));

        Console.WriteLine("443-2.jpg".GetUntilOrEmpty());
    }
}

Übrigens: Wenn Sie das Regex-Muster so ändern, "^(.*?)(-|$)"dass es entweder bis zum "-"Muster aufgenommen wird oder wenn das Muster nicht gefunden wurde, nehmen Sie alles bis zum Ende der Zeichenfolge auf.


0

Der LINQy-Weg

String.Concat ("223232-1.jpg" .TakeWhile (c => c! = '-'))

(Aber Sie müssen auf null testen;)

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.