6

I want to remove the substring of my string , it looks something like this :

At(Robot,Room3)

or

SwitchOn(Room2)

or

SwitchOff(Room1)

How can I remove all the characters from the left bracket ( to the right bracket ) , when I don't know their indexes ?

JAN
  • 21,236
  • 66
  • 181
  • 318

4 Answers4

13

If you know the string matches the pattern then you can do:

std::string str = "At(Robot,Room3)";
str.erase( str.begin() + str.find_first_of("("),
           str.begin() + str.find_last_of(")"));

or if you want to be safer

auto begin = str.find_first_of("(");
auto end = str.find_last_of(")");
if (std::string::npos!=begin && std::string::npos!=end && begin <= end)
    str.erase(begin, end-begin);
else
    report error...

You can also use the standard library <regex>.

std::string str = "At(Robot,Room3)";
str = std::regex_replace(str, std::regex("([^(]*)\\([^)]*\\)(.*)"), "$1$2");
bames53
  • 86,085
  • 15
  • 179
  • 244
  • `1st` suggestion is great ! +1 & chosen . – JAN Dec 14 '12 at 13:51
  • 1
    Works, but it would be a bit inefficient if you have, say `hugestring(tiny)`, because you're searching the same range twice. – Kerrek SB Dec 14 '12 at 13:53
  • @KerrekSB Switched to `find_last_of`, though it can still be inefficient, e.g. `tiny(tiny)hugestring`. – bames53 Dec 14 '12 at 14:08
  • Yeah, same problem. The efficient approach would be to resume searching just past the first parenthesis. – Kerrek SB Dec 14 '12 at 14:10
  • @KerrekSB But then what about `tiny(hugestring)tiny`? That's not efficient either... – bames53 Dec 14 '12 at 14:16
  • True, but if you're prepared to extract a large string, then I suppose that cost is acceptable. If you want, you can search forward *and* backwards at once to optimize for both extremes at the expense of the moderate cases. The point is that my initial suggestion is always better than your initial code, though other specific changes may conditionally improve the performance for certain use cases. – Kerrek SB Dec 14 '12 at 14:18
  • std::string str = "At(Robot,(Room3))"; What happen with this case if you need to remove between brackets and the result expected is At – ypriverol Sep 04 '17 at 20:52
  • 1
    @ypriverol Regular expressions aren't powerful enough to deal with matching parentheses, the regex method won't work in that case. The other method works fine because it's just deleting everything between the first opening paren and the last closing paren. – bames53 Sep 05 '17 at 19:12
2

If your compiler and standard library is new enough, then you could use std::regex_replace.

Otherwise, you search for the first '(', do a reverse search for the last ')', and use std::string::erase to remove everything in between. Or if there can be nothing after the closing parenthesis then find the first and use std::string::substr to extract the string you want to keep.

If the trouble you have is actually finding the parentheses the use std::string::find and/or std::string::rfind.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

You have to search for the first '(' then erase after until 'str.length() - 1' (assuming your second bracket is always at the end)

floppy12
  • 1,045
  • 6
  • 12
1

A simple and safe and efficient solution:

std::string str = "At(Robot,Room3)";

size_t const open = str.find('(');
assert(open != std::string::npos && "Could not find opening parenthesis");

size_t const close = std.find(')', open);
assert(open != std::string::npos && "Could not find closing parenthesis");

str.erase(str.begin() + open, str.begin() + close);

Never parse a character more than once, beware of ill-formed inputs.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722