How do I extract text that lies between parentheses (round brackets)?

C#.NetRegex

C# Problem Overview


I have a string User name (sales) and I want to extract the text between the brackets, how would I do this?

I suspect sub-string but I can't work out how to read until the closing bracket, the length of text will vary.

C# Solutions


Solution 1 - C#

If you wish to stay away from regular expressions, the simplest way I can think of is:

string input = "User name (sales)";
string output = input.Split('(', ')')[1];

Solution 2 - C#

A very simple way to do it is by using regular expressions:

Regex.Match("User name (sales)", @"\(([^)]*)\)").Groups[1].Value

As a response to the (very funny) comment, here's the same Regex with some explanation:

\(             # Escaped parenthesis, means "starts with a '(' character"
    (          # Parentheses in a regex mean "put (capture) the stuff 
               #     in between into the Groups array" 
       [^)]    # Any character that is not a ')' character
       *       # Zero or more occurrences of the aforementioned "non ')' char"
    )          # Close the capturing group
\)             # "Ends with a ')' character"

Solution 3 - C#

Assuming that you only have one pair of parenthesis.

string s = "User name (sales)";
int start = s.IndexOf("(") + 1;
int end = s.IndexOf(")", start);
string result = s.Substring(start, end - start);

Solution 4 - C#

Use this function:

public string GetSubstringByString(string a, string b, string c)
    {
        return c.Substring((c.IndexOf(a) + a.Length), (c.IndexOf(b) - c.IndexOf(a) - a.Length));
    }

and here is the usage:

GetSubstringByString("(", ")", "User name (sales)")

and the output would be:

sales

Solution 5 - C#

Regular expressions might be the best tool here. If you are not famililar with them, I recommend you install Expresso - a great little regex tool.

Something like:

Regex regex = new Regex("\\((?<TextInsideBrackets>\\w+)\\)");
string incomingValue = "Username (sales)";
string insideBrackets = null;
Match match = regex.Match(incomingValue);
if(match.Success)
{
	insideBrackets = match.Groups["TextInsideBrackets"].Value;
}

Solution 6 - C#

A regex maybe? I think this would work...

\(([a-z]+?)\)

Solution 7 - C#

string input = "User name (sales)";

string output = input.Substring(input.IndexOf('(') + 1, input.IndexOf(')') - input.IndexOf('(') - 1);

Solution 8 - C#

using System;
using System.Text.RegularExpressions;

private IEnumerable<string> GetSubStrings(string input, string start, string end)
{
    Regex r = new Regex(Regex.Escape(start) +`"(.*?)"`  + Regex.Escape(end));
    MatchCollection matches = r.Matches(input);
    foreach (Match match in matches)
    yield return match.Groups[1].Value;
}

Solution 9 - C#

int start = input.IndexOf("(") + 1;
int length = input.IndexOf(")") - start;
output = input.Substring(start, length);

Solution 10 - C#

Use a Regular Expression:

string test = "(test)"; 
string word = Regex.Match(test, @"\((\w+)\)").Groups[1].Value;
Console.WriteLine(word);

Solution 11 - C#

input.Remove(input.IndexOf(')')).Substring(input.IndexOf('(') + 1);

Solution 12 - C#

The regex method is superior I think, but if you wanted to use the humble substring

string input= "my name is (Jayne C)";
int start = input.IndexOf("(");
int stop = input.IndexOf(")");
string output = input.Substring(start+1, stop - start - 1);

or

string input = "my name is (Jayne C)";
string output  = input.Substring(input.IndexOf("(") +1, input.IndexOf(")")- input.IndexOf("(")- 1);

Solution 13 - C#

Here is a general purpose readable function that avoids using regex:

// Returns the text between 'start' and 'end'.
string ExtractBetween(string text, string start, string end)
{
  int iStart = text.IndexOf(start);
  iStart = (iStart == -1) ? 0 : iStart + start.Length;
  int iEnd = text.LastIndexOf(end);
  if(iEnd == -1)
  {
    iEnd = text.Length;
  }
  int len = iEnd - iStart;

  return text.Substring(iStart, len);
}

To call it in your particular example you can do:

string result = ExtractBetween("User name (sales)", "(", ")");

Solution 14 - C#

I'm finding that regular expressions are extremely useful but very difficult to write. So, I did some research and found this tool that makes writing them so easy.

Don't shy away from them because the syntax is difficult to figure out. They can be so powerful.

Solution 15 - C#

I've been using and abusing C#9 recently and I can't help throwing in Spans even in questionable scenarios... Just for the fun of it, here's a variation on the answers above:

	var input = "User name (sales)";
	var txtSpan = input.AsSpan();
	var startPoint = txtSpan.IndexOf('(') + 1;
	var length = txtSpan.LastIndexOf(')') - startPoint;
	var output = txtSpan.Slice(startPoint, length);

For the OP's specific scenario, it produces the right output. (Personally, I'd use RegEx, as posted by others. It's easier to get around the more tricky scenarios where the solution above falls apart).

A better version (as extension method) I made for my own project:

//Note: This only captures the first occurrence, but 
//can be easily modified to scan across the text (I'd prefer Slicing a Span)  
public static string ExtractFromBetweenChars(this string txt, char openChar, char closeChar)
{
    ReadOnlySpan<char> span = txt.AsSpan();
	int firstCharPos = span.IndexOf(openChar);
	int lastCharPos = -1;

	if (firstCharPos != -1) 
	{ 
		for (int n = firstCharPos + 1; n < span.Length; n++)
		{
			if (span[n] == openChar) firstCharPos = n; //This allows the opening char position to change
			if (span[n] == closeChar) lastCharPos = n;
			if (lastCharPos > firstCharPos) break;
			//This would correctly extract "sales" from this [contrived]
            //example: "just (a (name (sales) )))(test"
		}
		return span.Slice(firstCharPos + 1, lastCharPos - firstCharPos - 1).ToString();
	}
	return "";
}

Solution 16 - C#

This code is faster than most solutions here (if not all), packed as String extension method, it does not support recursive nesting:

public static string GetNestedString(this string str, char start, char end)
{
	int s = -1;
	int i = -1;
	while (++i < str.Length)
		if (str[i] == start)
		{
			s = i;
			break;
		}
	int e = -1;
	while(++i < str.Length)
		if (str[i] == end)
		{
			e = i;
			break;
		}
	if (e > s)
		return str.Substring(s + 1, e - s - 1);
	return null;
}

This one is little longer and slower, but it handles recursive nesting more nicely:

public static string GetNestedString(this string str, char start, char end)
{
	int s = -1;
	int i = -1;
	while (++i < str.Length)
		if (str[i] == start)
		{
			s = i;
			break;
		}
	int e = -1;
	int depth = 0;
	while (++i < str.Length)
		if (str[i] == end)
		{
			e = i;
			if (depth == 0)
				break;
			else
				--depth;
		}
		else if (str[i] == start)
			++depth;
	if (e > s)
		return str.Substring(s + 1, e - s - 1);
	return null;
}

Solution 17 - C#

Much similar to @Gustavo Baiocchi Costa but offset is being calculated with another intermediate Substring.

int innerTextStart = input.IndexOf("(") + 1;
int innerTextLength = input.Substring(start).IndexOf(")");
string output = input.Substring(innerTextStart, innerTextLength);

Solution 18 - C#

I came across this while I was looking for a solution to a very similar implementation.

Here is a snippet from my actual code. Starts substring from the first char (index 0).

 string separator = "\n";     //line terminator

 string output;
 string input= "HowAreYou?\nLets go there!";
 
 output = input.Substring(0, input.IndexOf(separator)); 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBen HView Question on Stackoverflow
Solution 1 - C#Jelly AmaView Answer on Stackoverflow
Solution 2 - C#DiadistisView Answer on Stackoverflow
Solution 3 - C#Ross GoddardView Answer on Stackoverflow
Solution 4 - C#artfulhackerView Answer on Stackoverflow
Solution 5 - C#JenniferView Answer on Stackoverflow
Solution 6 - C#chills42View Answer on Stackoverflow
Solution 7 - C#Nick AllenView Answer on Stackoverflow
Solution 8 - C#Bilal MradView Answer on Stackoverflow
Solution 9 - C#Gustavo Baiocchi CostaView Answer on Stackoverflow
Solution 10 - C#Will DeanView Answer on Stackoverflow
Solution 11 - C#RockcoderView Answer on Stackoverflow
Solution 12 - C#Ian GView Answer on Stackoverflow
Solution 13 - C#ChaimGView Answer on Stackoverflow
Solution 14 - C#katyholbView Answer on Stackoverflow
Solution 15 - C#Eric PhiriView Answer on Stackoverflow
Solution 16 - C#watbywbarifView Answer on Stackoverflow
Solution 17 - C#GauravPView Answer on Stackoverflow
Solution 18 - C#nikkView Answer on Stackoverflow