0

I have a long string of text delimited by a character (pipe character). I need to get the text between the 3rd and 4th pipes. Not sure how to go about this...

Open to regex or non-regex, whichever is the most efficient. Especially open to extension method if none exist to be able to pass in:

  • seperatorChar
  • index
michael
  • 14,844
  • 28
  • 89
  • 177
  • Couldn't you just indexOf with a start index of the previous pipe until you get to 3rd then substring to the index of the 4th pipe(starting from the index of the 3rd) ? Or just use string split on pipe :P – Brian Colvin Sep 21 '11 at 16:34
  • This indexOf suggestion would be the fastest by far, I would think, because it's not creating a bunch of separate strings (and an array!) that you don't need. All of the other solutions here create a lot of unneeded objects. – Joe Strout Mar 30 '16 at 18:29

5 Answers5

7

If

string textBetween3rdAnd4thPipe = "zero|one|two|three|four".Split('|')[3];

doesn't do what you mean, you need to explain in more detail.

Dour High Arch
  • 21,513
  • 29
  • 75
  • 90
2

This regex will store the text between the 3rd and 4th | you want in $1

/(?:([^|]*)|){4}/


Regex r = new Regex(@"(?:([^|]*)|){4}");
r.match(string);
Match m = r.Match(text);
trace(m.Groups[1].captures);
Jacob Eggers
  • 9,062
  • 2
  • 25
  • 43
2

Try This

public String GetSubString(this String originalStirng, StringString delimiter,Int32 Index)
{
   String output = originalStirng.Split(delimiter);
   try
   {
      return output[Index];
   }
   catch(OutOfIndexException ex)
   {
      return String.Empty;
   }
}
Amir Ismail
  • 3,865
  • 3
  • 20
  • 33
1

Here's my solution, which I expect to be more efficient than the others because it's not creating a bunch of strings and an array that are not needed.

/// <summary>
/// Get the Nth field of a string, where fields are delimited by some substring.
/// </summary>
/// <param name="str">string to search in</param>
/// <param name="index">0-based index of field to get</param>
/// <param name="separator">separator substring</param>
/// <returns>Nth field, or null if out of bounds</returns>
public static string NthField(this string str, int index, string separator=" ") {
    int count = 0;
    int startPos = 0;
    while (startPos < str.Length) {
        int endPos = str.IndexOf(separator, startPos);
        if (endPos < 0) endPos = str.Length;
        if (count == index) return str.Substring(startPos, endPos-startPos);
        count++;
        startPos = endPos + separator.Length;
    }
    return null;
}   
Joe Strout
  • 2,634
  • 2
  • 28
  • 39
  • only slightly unusual behavior of this implementation is that if the separator is not found, the entire search string is returned, that is "abc" & "|abc|" (if using pipes as per op) will both return "abc". – Brent Apr 30 '17 at 11:03
  • For what index? NthField("abc", 0, "|") certainly returns "abc", but NthField("|abc|", 0, "") should return empty string, because it starts with a delimiter. And as for field 1, NthField("abc", 1, "|"), that returns null (while for "|abc|" it returns "abc"). All as it should be, I think. Or have I missed something? – Joe Strout May 01 '17 at 14:07
1

You could do

     string text = str.Split('|')[3];

where str is your long string.

rohit89
  • 5,745
  • 2
  • 25
  • 42