Reputation: 115
In my code I want to remove a block of code that starts with a bracket and ends with a bracket. For example if I have this line
ENDPROGRAM { fprintf(sdfsdfsdfsd....) }
and after running the regex i want it to just end up with
ENDPROGRAM
I want to only delete code inside the bracket and the brackets themselves. I tried this command
:%s/\{[a-zA-Z0-0]*\}//g
but it says that pattern not found. Any suggestion? ENDPROGRAM is just an example, I have like DIV MULT etc etc
Upvotes: 0
Views: 545
Reputation: 5112
When something is broken, start simple and work up to what you need. Do not worry about the :s
command at first; instead, focus on getting the pattern (or regular expression) right.
\{
and you will get an error message. Oops, that should be just {
.{[a-zA-Z0-0]*
. Darn, that is not right, because you left out the space.{[a-zA-Z0-0 ]*
. Now we are getting somewhere, but we also want to match the parentheses and the dots: {[a-zA-Z0-0 ().]*
.0-9
instead of 0-0
, and you are done: {[a-zA-Z0-9 ().]*}
.At this point, you can take advantage of the fact that :s
uses the current search pattern by default, so all you need is :%s///
.
Upvotes: 2
Reputation: 8905
THIS looks like a job for: (dum da dum duuuuum!)
TEXT OBJECTS!
Place the cursor anywhere within the braces. Type daB.
WOOOOOOOAAAH what just happened?!
aB
is something called a "text object" in Vim. You could also have typed da{
or da}
in this situation. A text object is a thing that Vim's operators can act on. d is one such operator. I'm sure you know others: c, y, etc.
Visual mode also works on text objects. Instead of daB
, try vaB
. This will select all the text in the braces, plus the braces themselves. Most text objects also have an "inner" variant, for example ciB would delete everything inside the braces, and enter insert mode, leaving the braces intact.
There are text objects to work with HTML/XML tags, objects for working with quoted strings, objects for sentences and paragraphs, objects for words and WORDS, and more. See the full list at :help text-objects
.
Upvotes: 2
Reputation: 58500
Since you're using Vim, an alternative is to record a keyboard macro for this into a register, say register z.
qz
./ENDPROGRAM[enter]
f{
d%
q
.Now run the macro with @z
, and then repeat with @@
. Hold down your @
key to repeat rapidly.
For one-off jobs not involving tens of thousands of changes in numerous files, this kind of interactive approach works well. You visually confirm that the right thing is done in every place. The thing is that even if you fully automate it with regexes, you will still have to look at every change to confirm that the right thing was done before committing the code.
The first mistake in your regex is that the material between braces must only be letters and digits. (I'm assuming the 0-0 is a typo for 0-9). Note that you have other things between the braces such as spaces and parentheses. You want {.*}
: an open brace, followed by zero or more characters, followed by a closing brace. If it so happens that you have variants, like ENDPROGRAM { abc } { def }
, this regex will eat them too. The regex matches from the first open brace to the last closing one. Note also that the regex {[^}]*}
will not work if the block contains nested interior braces; it stops at the first closing brace, not the last one, and so ENDPROGRAM { { x } }
will turn to ENDPROGRAM }
.
The second mistake is that you are running this on all lines using the %
address. You only want to run this on lines that contain ENDPROGRAM
, in other words:
:g/ENDPROGRAM/s/ {.*}//
"For all lines that contain a match for ENDPROGRAM
, find a space followed by some bracketed text, and replace it with nothing." Or else:
:%s/ENDPROGRAM {.*}/ENDPROGRAM/
Upvotes: 2