Dapatkan Substring - semuanya sebelum karakter tertentu


124

Saya mencoba mencari cara terbaik untuk mendapatkan semuanya sebelum - karakter dalam string. Beberapa contoh string ada di bawah. Panjang string sebelumnya - bervariasi dan bisa berapa saja

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

jadi saya membutuhkan nilai dari indeks awal 0 ke kanan sebelum -. Jadi substringnya akan menjadi 223232, 443, dan 34443553

Jawaban:


144

Contoh .Net Fiddle

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;
    }
}

Hasil:

223232
443
34443553
344

34

2
Tolong bantu mereka dan tambahkan pemeriksaan kesalahan juga dengan asumsi dia berencana untuk membuat fungsi dari ini :)
Josh

Terima kasih, saya hampir saja melakukannya, tetapi ingin tahu apakah ada yang memiliki cara berbeda untuk melakukannya selain kombo ini. Tapi ya ini berhasil dengan baik dan masih cukup singkat.
PositiveGuy

14
Jika Anda menginginkan satu baris tanpa kehilangan pemeriksaan "tidak ditemukan" yang tepat maka Anda dapat melakukan sesuatu seperti ini:string result = source.Substring(0, Math.Max(source.IndexOf('-'), 0))
LukeH

2
Alih-alih s.Substring(0, n)salah satu dapat digunakan s.Remove(n)ketika diketahui (seperti di sini) bahwa panjang string sbenar-benar melebihi n.
Jeppe Stig Nielsen

@ LukeH Jika IndexOf mengembalikan -1 dalam contoh Anda, maka string kosong akan dikembalikan, bukan?
hancurkan

124

Gunakan fungsi split .

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();
}

Jika string Anda tidak memiliki a -maka Anda akan mendapatkan seluruh string.


4
Dan jika Anda memiliki lebih dari satu tanda hubung, Anda mendapatkan beberapa elemen dalam array Anda.
James Dunne

2
Memang, James, jadi ini hanya akan menjadi solusi jika Anda mengharapkan hanya satu tanda hubung. Saya kira Anda dapat menggunakan metode Linq seperti lewati dan agregat untuk mendapatkan apa yang Anda inginkan, tetapi kemudian Anda memiliki lebih banyak kode daripada metode yang telah diusulkan. Itu semua tergantung pada seberapa banyak Anda tahu tentang data yang masuk.
Dominic Cronin

7
Dan beberapa tahun kemudian, saya baru menyadari bahwa saya terlalu cepat untuk mengakui poin James. Pertanyaannya menanyakan bagaimana menemukan string sebelum karakter tertentu. Dengan demikian, contoh lebih lanjut dari karakter itu tidak relevan, dan mengambil [0] akan "berhasil". Tentunya masih tergantung seberapa besar kita mempercayai data yang masuk. Bagaimana jika tidak ada '-' sama sekali?
Dominic Cronin

1
Saya pikir poin @JamesDunne adalah bahwa dengan membelah menjadi sebuah array, Anda membuat banyak string yang tidak perlu - sampah yang tidak perlu.
hancurkan

1
Saya tidak akan khawatir tentang "sampah yang tidak perlu". Setiap string tambahan yang dibuat dengan cara ini akan segera tidak dapat dijangkau dan oleh karena itu dikumpulkan dalam generasi 0, yang memang merupakan overhead yang sangat rendah. Desain pengumpul sampah secara eksplisit dimaksudkan untuk memungkinkan sejumlah besar barang berumur pendek digunakan dengan hampir tanpa biaya.
Dominic Cronin

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

upvote karena saya perlu tahu indeks pemisah
Piero Alberto

3
Ini sebenarnya adalah jawaban yang sama seperti yang Fredou berikan (saat ini jawaban teratas) kecuali bahwa ini menghilangkan penanganan kasus di mana tidak ada kecocokan yang ditemukan.
Dominic Cronin

7

Hal-hal telah berubah sedikit sejak utas ini dimulai.

Sekarang, Anda bisa menggunakan

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

Bagaimana ini membandingkan kinerja yang bijaksana dengan kombinasi IndexOf dan Substring yang jelas? Saya berasumsi itu menambahkan setiap karakter ke StringBuilder, dan kemudian menghasilkan string di bagian akhir. Ada juga beberapa pemanggilan fungsi yang tercampur. Akan lebih baik jika Substring bisa mengambil -1 sebagai argumen "panjang" yang berarti "akhir string".
hancurkan

1
Lebih buruk untuk efisiensi. Seperti yang Anda katakan, ini menggunakan pembuat string, dan setelah memeriksa kode tersebut muncul untuk memanggil ToString pada setiap karakter. Lebih jelas jika Anda mencari lebih dari satu karakter, karena Anda dapat menulis ulang lambda dengan mudah.
Anthony Wieser

5

Salah satu cara untuk melakukannya adalah dengan menggunakan String.Substringbersama dengan String.IndexOf:

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

Mulai dari posisi 0, kembalikan semua teks ke atas, tetapi tidak termasuk, tanda hubung.


jika indeks <= 0 Anda harus mengembalikan string.empty.
Tidak Ada Pengembalian Dana Tidak Ada Pengembalian

5
@NRNR: jika Anda berkata begitu. OP mengetahui persyaratan bisnis, bukan Anda atau saya.
Michael Petrotta

0

Membangun jawaban 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

Anda dapat menggunakan ekspresi reguler untuk tujuan ini, tetapi sebaiknya hindari pengecualian tambahan saat string masukan tidak cocok dengan ekspresi reguler.

Pertama untuk menghindari sakit kepala ekstra karena melarikan diri ke pola regex - kita bisa menggunakan fungsi untuk tujuan itu:

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

Saya tahu bahwa ini tidak melakukan apa-apa - karena "-" sama dengan Regex.Escape("=") == "=", tetapi akan membuat perbedaan misalnya jika karakternya @"\".

Kemudian kita perlu mencocokkan dari mengemis string ke string ending, atau bergantian jika ending tidak ditemukan - maka tidak ada yang cocok. (String kosong)

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

Jika aplikasi Anda sangat penting dalam performa - maka pisahkan baris untuk Regex baru, jika tidak - Anda dapat memiliki semuanya dalam satu baris.

Dan akhirnya cocokkan dengan string dan ekstrak pola yang cocok:

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

Dan setelah itu Anda dapat menulis fungsi terpisah, seperti yang dilakukan di jawaban lain, atau menulis fungsi lambda sebaris. Saya telah menulis sekarang menggunakan kedua notasi - fungsi lambda inline (tidak mengizinkan parameter default) atau pemanggilan fungsi terpisah.

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());
    }
}

Btw - mengubah pola regex menjadi "^(.*?)(-|$)"akan memungkinkan untuk mengambil baik sampai "-"pola atau jika pola tidak ditemukan - ambil semuanya sampai akhir string.


0

Cara LINQy

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

(Tapi, Anda perlu menguji null;)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.