patterncsharpMinor
Removing curly braces and contents inside it
Viewed 0 times
bracesremovingcontentsandcurlyinside
Problem
Lets say I have a string like this:
Just consider the indexes beyond #9 are 10,11,12,13, and 14 respectively.
My code turns
How the matching works:
When you find a closing brace (
A simple regex such as
```
internal class BracketPair
{
private readonly string _originalString;
private int _endIndex;
public BracketPair(string originalString, int startIndex)
{
_originalString = originalString;
StartIndex = startIndex;
Children = new List();
NestedLevel = 0;
}
public int StartIndex { get; }
public int EndIndex {
get { return _endIndex; }
set {
_endIndex = value;
IsComplete = true;
}
}
//If there are matching pairs of { and } for this
public bool IsComplete { get; private set; }
public List Children { get; }
public int NestedLevel { get; set; }
public override string ToString()
{
if (!IsComplete)
throw new InvalidOperationException("BracketPair is incomplete");
return _original
string s = "A }{ B { C } }{"
//Indexes: 0123456789ABCDEJust consider the indexes beyond #9 are 10,11,12,13, and 14 respectively.
My code turns
s to "A ", because whatever is inside matching curly braces gets removed.How the matching works:
When you find a closing brace (
}), the last opening brace ({) which does not yet have an associated closing brace should be associated with the closing brace we just found. For example, in the above string I have given, the closing brace at index 2 cannot have an opening brace. So it is "Incomplete". the brace at index 3 is paired with brace at index 13. And brace at index 7 is paired with brace at index 11. Brace at index 14 does not have a closing brace so it is also "incomplete". I hope you understand what I am trying to do :)A simple regex such as
{[^}]*} can match the curly braces but it does not handle nesting very well. So I wrote a class to parse this. But I found that compared to regex, my method is very slow. Regex takes 0ms but my method takes 3ms. I would appreciate if anyone could tell me how I can optimise it further. ```
internal class BracketPair
{
private readonly string _originalString;
private int _endIndex;
public BracketPair(string originalString, int startIndex)
{
_originalString = originalString;
StartIndex = startIndex;
Children = new List();
NestedLevel = 0;
}
public int StartIndex { get; }
public int EndIndex {
get { return _endIndex; }
set {
_endIndex = value;
IsComplete = true;
}
}
//If there are matching pairs of { and } for this
public bool IsComplete { get; private set; }
public List Children { get; }
public int NestedLevel { get; set; }
public override string ToString()
{
if (!IsComplete)
throw new InvalidOperationException("BracketPair is incomplete");
return _original
Solution
I would definitely use a regex for this. It might not be the most performant solution but I think it's the simplest. You can handle the nesting problem by making the
I don't know whether it will match all of your inputs but it works for the example you've given. The while loop is a bit annoying - if you don't have any nesting it will only run once but if you have a heavily nested string you'll end up running the regex quite a few times.
* quantifier lazy by appending a ? to it in your pattern:public static string HideInternalNote(string input)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
if (input == string.Empty)
{
return input;
}
var inputWithBracePairsRemoved = RemovePairedBraces(input);
var result = RemoveAllBraces(inputWithBracePairsRemoved);
return result;
}
private static string RemoveAllBraces(string input)
{
return input
.Replace("{", string.Empty)
.Replace("}", string.Empty);
}
private static string RemovePairedBraces(string input)
{
var expression = new Regex("{[^{]*?}");
// OR
// var expression = new Regex("{[^{}]*}");
var previous = input;
string current;
while (true)
{
current = expression.Replace(previous, string.Empty);
if (current == previous)
{
break;
}
previous = current;
}
return current;
}I don't know whether it will match all of your inputs but it works for the example you've given. The while loop is a bit annoying - if you don't have any nesting it will only run once but if you have a heavily nested string you'll end up running the regex quite a few times.
Code Snippets
public static string HideInternalNote(string input)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
if (input == string.Empty)
{
return input;
}
var inputWithBracePairsRemoved = RemovePairedBraces(input);
var result = RemoveAllBraces(inputWithBracePairsRemoved);
return result;
}
private static string RemoveAllBraces(string input)
{
return input
.Replace("{", string.Empty)
.Replace("}", string.Empty);
}
private static string RemovePairedBraces(string input)
{
var expression = new Regex("{[^{]*?}");
// OR
// var expression = new Regex("{[^{}]*}");
var previous = input;
string current;
while (true)
{
current = expression.Replace(previous, string.Empty);
if (current == previous)
{
break;
}
previous = current;
}
return current;
}Context
StackExchange Code Review Q#116809, answer score: 5
Revisions (0)
No revisions yet.