gotqn
gotqn

Reputation: 43666

How to remove parentheses only when the whole text is surrounded by them?

I want to remove parentheses only when the whole text is surrounded by them. For example:

(text (text) text)

need's to be convert to:

text (text) text

I have a very simple check:

value = (value [0] == '(' && value [value .Length - 1] == ')') ? value.Substring(1, value .Length - 2) : value;

but it fails and incorrectly removes the parentheses of these kind of strings:

(text (text) ) text (text)

Could anyone tell a way to handle all cases? Using regular expression is OK as well.

Note, that the parentheses are balanced. For example, such case is not possible:

( text ( text )

Upvotes: 3

Views: 482

Answers (3)

paparazzo
paparazzo

Reputation: 45106

Ran a few test cases and I think this is good

public string CleanString(string CleanMe)
{
    if (string.IsNullOrEmpty(CleanMe)) return CleanMe;
    string input = CleanMe.Trim();
    if (input.Length <= 2) return input;
    if (input[0] != '(') return input;
    if (input[input.Length-1] != ')') return input;
    int netParen = 1;  // starting loop at 1 have one paren already
    StringBuilder sb = new StringBuilder();
    for (int i = 1; i < input.Length-1; i++)
    {
        char c = input[i];
        sb.Append(c);
        if (c == '(') netParen++;
        else if (c == ')') netParen--;
        if (netParen == 0) return input;  // this is the key did the () get closed out
    }
    return sb.ToString();
}

I started this before the answer from Amit but I think it is the same basic logic

Upvotes: 1

Juan M. Elosegui
Juan M. Elosegui

Reputation: 6981

This extension method should work;

public static class StringExtensions
{
    public static string RemoveParentheses(this string value)
    {
        if (value == null || value[0] != '(' || value[value.Length - 1 ] != ')') return value;

        var cantrim = false;
        var openparenthesesIndex = new Stack<int>();
        var count = 0;
        foreach (char c in value)
        {
            if (c == '(')
            {
                openparenthesesIndex.Push(count);
            }
            if (c == ')')
            {
                cantrim = (count == value.Length - 1 && openparenthesesIndex.Count == 1 && openparenthesesIndex.Peek() == 0);
                openparenthesesIndex.Pop();
            }
            count++;
        }

        if (cantrim)
        {
            return value.Trim(new[] { '(', ')' });
        }
        return value;
    }
}

Use it like this

Console.WriteLine("(text (text) ) text (text)".RemoveParentheses());

Upvotes: 1

Amit
Amit

Reputation: 46361

Use a simple loop for testing, if it's "valid" for removal, remove first & last:

bool isValid = value[0] == '(' && value[value.Length - 1] == ')';
int i = 1;
int c = 0;
for(; isValid && c >= 0 && i < value.Length - 1; i++)
{
  if(value[i] == '(')
    c++;
  else if(value[i] == ')')
    c--;
}

if(isValid && i == (value.Length - 1) && c == 0)
  value = value.Substring(1, value.Length - 2);

Upvotes: 4

Related Questions