RGuest
RGuest

Reputation: 19

C# Get particular string between two string (multiple occurance)

how can I retrieve both string between STRING & END in this sentence

"This is STRING a222 END, and this is STRING b2838 END."

strings that I want to get:

a222 
b2838

Following is my code, and i only manage to get first string which is a222


string myString = "This is STRING a222 END, and this is STRING b2838 END.";

int first = myString.IndexOf("STRING") + "STRING".Length;
int second= myString.LastIndexOf("END");

string result = St.Substring(first, second - first);

.

Upvotes: 0

Views: 162

Answers (5)

Biju Kalanjoor
Biju Kalanjoor

Reputation: 552

string myString = "This is STRING a222 END, and this is STRING b2838 END.";
// Fix the issue based on @PaulF's comment.
if (myString.StartsWith("STRING"))
     myString = $"DUMP {myString}";

var arr = myString.Split(new string[] { "STRING", "END" }, StringSplitOptions.RemoveEmptyEntries);

for (int i = 0; i < arr.Length; i++)
{
      if(i%2 > 0)
      {
          // This is your string
          Console.WriteLine(arr[i].Trim());
      }
}

Upvotes: 0

MikeJ
MikeJ

Reputation: 1369

You've already got some good answers but I'll add another that uses ReadOnlyMemory from .NET core. That provides a solution that doesn't allocate new strings which can be nice. C# iterators are a common way to transform one sequence, of chars in this case, into another. This method would be used to transform the input string into sequence of ReadOnlyMemory each containing the tokens your after.

    public static IEnumerable<ReadOnlyMemory<char>> Tokenize(string source, string beginPattern, string endPattern)
    {
        if (string.IsNullOrEmpty(source) ||
            string.IsNullOrEmpty(beginPattern) ||
            string.IsNullOrEmpty(endPattern))
            yield break;

        var sourceText = source.AsMemory();

        int start = 0;

        while (start < source.Length)
        {
            start = source.IndexOf(beginPattern, start);

            if (-1 != start)
            {
                int end = source.IndexOf(endPattern, start);

                if (-1 != end)
                {
                    start += beginPattern.Length;
                    yield return sourceText.Slice(start, (end - start));
                }
                else
                    break;

                start = end + endPattern.Length;
            }
            else
            {
                break;
            }
        }
    }

Then you'd just call it like so to iterate over the tokens...

    static void Main(string[] args)
    {
        const string Source = "This is STRING a222 END, and this is STRING b2838 END.";

        foreach (var token in Tokenize(Source, "STRING", "END"))
        {
            Console.WriteLine(token);
        }
    }

Upvotes: 1

Prasad Telkikar
Prasad Telkikar

Reputation: 16049

You can iterate over indexes,

string myString = "This is STRING a222 END, and this is STRING b2838 END.";
//Jump to starting index of each `STRING`
for(int i = myString.IndexOf("STRING");i > 0; i = myString.IndexOf("STRING", i+1))
{
    //Get Index of each END
    var endIndex = myString.Substring(i + "STARTING".Length).IndexOf("END");
    //PRINT substring between STRING and END of each occurance
    Console.WriteLine(myString.Substring(i + "STARTING".Length-1, endIndex));
}

.NET FIDDLE


In your case, STRING..END occurs multiple times, but you were getting index of only first STRING and last index of END which will return substring, starts with first STRING to last END.

i.e.

a222 END, and this is STRING b2838 

Upvotes: 1

Sowmyadhar Gourishetty
Sowmyadhar Gourishetty

Reputation: 1878

Here is the solution using Regular Expressions. Working Code here

var reg = new Regex("(?<=STRING ).*?(?= END)");
var matched = reg.Matches("This is STRING a222 END, and this is STRING b2838 END.");

foreach(var m in matched)
{
   Console.WriteLine(m.ToString());
}

Upvotes: 2

Jorn Vanloofsvelt
Jorn Vanloofsvelt

Reputation: 376

You can pass a value for startIndex to string.IndexOf(), you can use this while looping:

    IEnumerable<string> Find(string input, string startDelimiter, string endDelimiter)
    {
        int first = 0, second;

        do
        {
            // Find start delimiter
            first = input.IndexOf(startDelimiter, startIndex: first) + startDelimiter.Length;

            if (first == -1) 
                yield break;


            // Find end delimiter
            second = input.IndexOf(endDelimiter, startIndex: first);

            if (second == -1)
                yield break;


            yield return input.Substring(first, second - first).Trim();
            first = second + endDelimiter.Length + 1;
        }
        while (first < input.Length);
    }

Upvotes: 1

Related Questions