1

EDIT: I am retiring this question (via vote to close) as I have asked a better question here: Use REGEX to replace X(...) with X{...}

I am updating some code to C++11 that has a tremendous number of Foo() initialisers which should be replaced by Foo{}.

It is not as simple as straightforward search and replace, as nested brackets are possible, e.g. Bar(w("hello"))

I'm looking for something simple that removes most of the effort. (Something that distinguishes when to keep () and when to switch for {} would be very tricky)

I noticed Xcode supports regex search and replace. Is it possible to use this mechanism to replace:

Foo(BLAH) 

with

Foo{BLAH}

where BLAH just has to balance the brackets?

I could then run a separate search&replace for each of Foo, Bar, ... .

Community
  • 1
  • 1
P i
  • 29,020
  • 36
  • 159
  • 267

1 Answers1

3

The general problem you're facing is that of "balanced brackets", which is something that's very difficult to do with most regular expression implementations. However, as long as you don't have constructors that contain constructors of the same type, and you don't have more than one constructor on a single line:

Replace

Foo\((.*)\)

With

Foo{$1}

Note that following patterns will cause problems:

Foo(Foo()) => Foo{Foo()}

Foo(), Foo() => Foo{}

As the OP noted in the comments, this also caused problems with expected inputs such as:

Object( pyob, owned ) { validate(); } => Object{ pyob, owned }; }

The way to get around this is to use lazy quantifiers (instead of greedy). The problem with using lazy quantifiers is that it will then only get the innermost instances; you'll have to repeat the replacement for nested constructors. Quantifiers can be made lazy by putting a question mark after them. So you will replace:

Foo\((.*?)\)

With:

Foo{$1}

Now if you have this:

Foo(Foo())

The first replacement will yield:

Foo(Foo{})

And then if you run the replacement again, you will get:

Foo{Foo{}}
Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • Thanks, now that this looks possible I'm investigating regex syntax. Is there any way around those restrictions? I frequently have multiple Foo(...) on one line, e.g. 'Ob x = add( Ob(3), Ob(4) ) – P i Nov 21 '14 at 00:20
  • PS I assume you meant'Foo{$1}' – P i Nov 21 '14 at 00:22
  • Actually this is great. However, it stumbles on 'Object( pyob, owned ) { validate(); }' -- because it selects between the first '(' and the last ')', so it converts that to Object{ pyob, owned ) { validate(}; } – P i Nov 21 '14 at 00:32
  • The way to solve both of these problems is to use lazy quantifiers (greedy is the default). I'll update my answer. – Ethan Brown Nov 21 '14 at 15:48