Home > Software design >  Search and replace with backreference with modification
Search and replace with backreference with modification

Time:12-07

Question for vim power users:

file1.txt

Some list
 - line 1
 - line 2

Example of payload:

```json
{
    "order_id": "ABC123",
    "postcode": "A1 B22",
    "items": [1, 2, 3]
}
```

More text follows.

My goal is to:

  • match everything that is in between ```json and ```
  • get rid of those prefix/suffix
  • and prepend each line with extra spaces (add indentation). The result would be something like that:

file2.txt

Some list
 - line 1
 - line 2

Example of payload:

    {
        "order_id": "ABC123",
        "postcode": "A1 B22",
        "items": [1, 2, 3]
    }

More text follows.

So far I managed to non-greedy match everything between json and backticks via:

%s/```json\(\_.\{-}\)```/\1/g

But prepending each line of \1 is an entirely different story.

Things I experimented with is:

  • submatch (i.e. %s/```json\(\_.\{-}\)```/\=submatch(1)/g)
  • trying to chain replaces (but I have no idea how to do it)

Any help/suggestion?

CodePudding user response:

I would do it in two steps:

:g/```json/.,/```/s/^/    /
:g/```/d

The first step:

  • :g/<pattern>/<command> executes <command> on each line matching <pattern>.
  • ```json is our <pattern>, the rest is our <command>, a simple substitution.
  • .,/```/ is a range that covers every line from the current line, ., to the line of the next ```.
  • s/^/ / essentially prepends the line with 4 spaces.

This effectively indents the whole fenced block:

    ```json
    {
        "order_id": "ABC123",
        "postcode": "A1 B22",
        "items": [1, 2, 3]
    }
    ```

The second step:

  • :g/<pattern>/<command> executes <command> on each line matching <pattern>, like above.
  • ``` is our <pattern>.
  • d is our <command>.

This effectively removes the extraneous fences:

    {
        "order_id": "ABC123",
        "postcode": "A1 B22",
        "items": [1, 2, 3]
    }

See :help :global.

  • Related