Pertanyaan Ekstrak semua string antara dua string


Saya mencoba mengembangkan metode yang akan cocok dengan semua string antara dua string:

Saya sudah mencoba ini tetapi hanya mengembalikan pertandingan pertama:

string ExtractString(string s, string start,string end)
        {
            // You should check for errors in real-world code, omitted for brevity

            int startIndex = s.IndexOf(start) + start.Length;
            int endIndex = s.IndexOf(end, startIndex);
            return s.Substring(startIndex, endIndex - startIndex);
        }

Anggaplah kita memiliki string ini

String Text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"

Saya ingin fungsi c # melakukan hal berikut:

public List<string> ExtractFromString(String Text,String Start, String End)
{
    List<string> Matched = new List<string>();
    .
    .
    .
    return Matched; 
}
// Example of use 

ExtractFromString("A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2","A1","A2")

    // Will return :
    // FIRSTSTRING
    // SECONDSTRING
    // THIRDSTRING

Terima kasih untuk bantuannya !


9
2017-12-08 18:44


asal


Jawaban:


private static List<string> ExtractFromString(
    string text, string startString, string endString)
{            
    List<string> matched = new List<string>();
    int indexStart = 0, indexEnd=0;
    bool exit = false;
    while(!exit)
    {
        indexStart = text.IndexOf(startString);
        indexEnd = text.IndexOf(endString);
        if (indexStart != -1 && indexEnd != -1)
        {
            matched.Add(text.Substring(indexStart + startString.Length, 
                indexEnd - indexStart - startString.Length));
            text = text.Substring(indexEnd + endString.Length);
        }
        else
            exit = true;
    }
    return matched;
}

25
2017-12-08 18:57



Berikut ini solusi menggunakan RegEx. Jangan lupa untuk menyertakan pernyataan menggunakan berikut.

using System.Text.RegularExpressions

Ini akan mengembalikan hanya teks dengan benar antara string awal dan akhir yang diberikan.

Tidak akan dikembalikan:

akslakhflkshdflhksdf

Akan dikembalikan:

FIRSTSTRING
SECONDSTRING
THIRDSTRING

Ini menggunakan pola ekspresi reguler [start string].+?[end string]

String awal dan akhir diloloskan jika mereka mengandung karakter khusus ekspresi reguler.

    private static List<string> ExtractFromString(string source, string start, string end)
    {
        var results = new List<string>();

        string pattern = string.Format(
            "{0}({1}){2}", 
            Regex.Escape(start), 
            ".+?", 
             Regex.Escape(end));

        foreach (Match m in Regex.Matches(source, pattern))
        {
            results.Add(m.Groups[1].Value);
        }

        return results;
    }

Anda bisa membuatnya menjadi metode ekstensi String seperti ini:

public static class StringExtensionMethods
{
    public static List<string> EverythingBetween(this string source, string start, string end)
    {
        var results = new List<string>();

        string pattern = string.Format(
            "{0}({1}){2}",
            Regex.Escape(start),
            ".+?",
             Regex.Escape(end));

        foreach (Match m in Regex.Matches(source, pattern))
        {
            results.Add(m.Groups[1].Value);
        }

        return results;
    }
}

Useage:

string source = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
string start = "A1";
string end = "A2";

List<string> results = source.EverythingBetween(start, end);

9
2017-12-08 19:18



text.Split(new[] {"A1", "A2"}, StringSplitOptions.RemoveEmptyEntries);

4
2017-12-08 19:00



Anda dapat membagi string menjadi larik menggunakan pengidentifikasi awal dalam kode berikut:

String str = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";

String[] arr = str.Split("A1");

Kemudian iterate melalui array Anda dan hapus 2 karakter terakhir dari setiap string (untuk menghapus A2). Anda juga harus membuang elemen array pertama karena akan kosong dengan asumsi string dimulai dengan A1.

Kode belum diuji, saat ini pada perangkat seluler


1
2017-12-08 18:54



Ini adalah solusi umum, dan saya yakin lebih banyak kode yang bisa dibaca. Tidak diuji, jadi berhati-hatilah.

public static IEnumerable<IList<T>> SplitBy<T>(this IEnumerable<T> source, 
                                               Func<T, bool> startPredicate,
                                               Func<T, bool> endPredicate, 
                                               bool includeDelimiter)
{
    var l = new List<T>();
    foreach (var s in source)
    {
        if (startPredicate(s))
        {
            if (l.Any())
            {
                l = new List<T>();
            }
            l.Add(s);
        }
        else if (l.Any())
        {
            l.Add(s);
        }

        if (endPredicate(s))
        {
            if (includeDelimiter)
                yield return l;
            else
                yield return l.GetRange(1, l.Count - 2);

            l = new List<T>();
        }
    }
}

Dalam kasus Anda, Anda dapat menelepon,

var text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
var splits = text.SplitBy(x => x == "A1", x => x == "A2", false);

Ini bukan yang paling efisien ketika Anda tidak ingin pembatas dimasukkan (seperti kasus Anda) dalam hasil tetapi efisien untuk kasus yang berlawanan. Untuk mempercepat kasus Anda, seseorang dapat langsung memanggil GetEnumerator dan memanfaatkan MoveNext.


0
2017-07-25 09:47