0

I am editing a markdown file with vim. This file exist many string \norm{ some string }. I want to replace them by \| some string \|. Does there exist any quick way? Thanks very much.

The answer in Find and replace strings in vim on multiple lines can not answer my question. It just talk about general replacing for one line and multi line. Here I want to replace a surrounding and keep the string in the surrounding.

Huayi Wei
  • 719
  • 1
  • 6
  • 14

2 Answers2

1

What you're looking for are so-called capture groups and backreferences. Provided there are no nested forms (curly braces inside do not mean a problem in themselves) and forms spanning multiple lines, a quick solution could be: %s/\\norm {\(.*\)}/\\|\1\\|/g.

The \1 in the substitution part refers to the group captured by \(.*\), i.e. the original content inside the outermost pair of curly braces. See e.g. http://www.vimregex.com/#backreferences for more.

pamacs
  • 100
  • 6
  • Thanks for your reply. This reply can partially answer my question. There exist some `{}` in my case, eg. `\norm{ A^{-1} }`. – Huayi Wei Mar 25 '19 at 02:08
  • 1
    @HuayiWei he's giving you the resources to find what you need to figure out how to do it yourself, he's not going to give you the exact regex. – Stun Brick Mar 25 '19 at 08:41
  • 1
    @StunBrick Thanks for your suggestion. – Huayi Wei Mar 25 '19 at 08:48
  • 1
    @HuayiWei Sorry, that was a typo, "do _not_ mean a problem" was intended. If yout try it, you can see that it works with your example, and the result will be `\| A^{-1} \|`. The case which this regex cannot handle is e.g. `\norm { ... \norm { ... } }` (but you could do multiple rounds :) ). If you have arbitrary levels of nesting, that actually cannot be handled by a simple regex form at all, since you need some form of recursion for that. See for this e.g.: https://stackoverflow.com/questions/17759004/how-to-match-string-within-parentheses-nested-in-java. – pamacs Mar 25 '19 at 09:29
0

You could also use a macro to accomplish what you want.

Place your cursor on the first line that have the pattern you want to substitute. Then start recording the macro:

qq0ldwr|$xi\|ESCjq

Meaning:

qq  = start recording a macro (q) in register q
0   = move to the beginning of the line
l   = move one char to the right
dw  = delete the word
r|  = substitute what is under the cursor with a "|"
$   = move to the end of line
x   = delete last char of the line
i   = insert mode
\|  = insert chars "\|"
ESC = exit insert mode
j   = move to next line
q   = stop recording

Execute the macro with:

@q

Execute the macro once again:

@@

Keep doing it for as many lines as needed, or use:

<number>@@
ex. 100@@

To execute the macro number times.

Doktorn
  • 687
  • 5
  • 7