2

My file contains multiple blocks looking like this

some Test "^M
^M
^M
"some more text

I'd like to remove these passages (including the "), but can't seem to fine the right regex.

EDIT: I already know about the escape sequence ^M and how to add it into the regex (CTRL-V + CTRL-M) but I struggle to find the right regex. In words the search looks like this:

The passage starts and ends with the " character in between there are only newlines and ^M (the actual number of characters between the " varies, but there is at least one ^M).

I was thinking about something like this \"^M\_s\+ but this expression doesn't work. What am I doing wrong?

1 Answer 1

7

Characters displayed by ^ followed by a capital letter (or a small number of other symbols, such as ^[) are the usual notation for the ASCII character produced by pressing that letter while holding the Control key.

Vim will typically show these in a distinct color or highlight (to indicate it's displaying a Control-sequence and not two separate characters, the caret character followed by another character.) Furthermore, when you move the cursor through this character, the cursor will "jump" through the second character and will only stop on the ^.

So ^M is actually the way to display Ctrl+M

But simply pressing that character while in insert mode or while entering a search term will not work, since that control character has a special purpose, which is the same as the "Return" character. (Many/most other control sequences have special purposes as well.)

In order to be able to enter it, you need to escape it, and you can use Ctrl+V for that purpose. (See :help c_CTRL-V for more details.)

So in order to search for it, you can start search with /, then press Ctrl+V, then Ctrl+M. You'll see the ^M notation. You can then search for that character. It's fine to mix in other characters as part of the search expression as well.

(As a small aside, the ^M character is also a bit special because it is used in DOS line endings, so having your lines ending with a ^M typically indicates a DOS file format. If you have 'fileformats' include dos, Vim is usually able to detect your file is using DOS fileformat and convert that from you on reading the file. You can also typically force that by using :e ++ff=dos ... when reading the file, see :help ++ff for details.)


EDIT: If you want to match this character in a regular expression, you can also use \r, which is specifically for the ^M character.

If you want to match a double quote followed by a sequence of whitespace including ^M characters, you can use the following:

/"\r\_[ \t\r]\+

If you want to replace those with a single newline after the double quote:

:%s/"\r\_[ \t\r]\+/"\r/

You need to use a \_[] group, a simple \_s doesn't work since \s expands to <Space> and <Tab> alone.

The _ takes care of the newline (also possible to use \n inside the group), then you need to consider space and tab ([ \t]), same as \s would, and include \r for the ^Ms.

Note that on the replacement side of a :s command, \r (or even ^M entered with ^V^M or ^V, "Enter") means adding a line break! So you should use that rather than \n on that side of the command. See :help s/\r for details on that.

4
  • 3
    If you are on a Windows machine, you will need to use Ctrl + Q instead of Ctrl + V. Commented Mar 10, 2020 at 9:46
  • 1
    Thank you. I already knew about the escape sequence, but I'm not sure how to write the regular expression. In words it looks like this: The passage is starting and ending with " in between there are exclusively ^M and newlines. How can I write this expression? Commented Mar 10, 2020 at 11:56
  • I clarified my question with an edit. Commented Mar 10, 2020 at 12:01
  • @user7802048 Added an edit to include information on how to match that in a regex. Not completely clear to me what you're trying to achieve... Collapse the whitespace and newlines? Are you working with a DOS file format by any chance? Wouldn't if be easier to tell Vim to recognize it as such? Anyways, I hope the update is helpful too.
    – filbranden
    Commented Mar 10, 2020 at 15:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.