简体   繁体   English

如何在 Vim 中用正则表达式匹配行尾而不是段落?

[英]How to match the end of a line but not a paragraph with a regex in Vim?

I am trying to join all lines in a paragraph, but not join one paragraph with the next.我正在尝试将一个段落中的所有行连接起来,但不将一个段落与下一个段落连接起来。

In my text file, the paragraph is not defined by blank lines in between them, but with a period at the end of the line.在我的文本文件中,段落不是由它们之间的空行定义的,而是在行尾有一个句点。 There could be white spaces after the period but it still defines the end of the paragraph.句点之后可能有空格,但它仍然定义了段落的结尾。

So, I wanted to do a macro that jumps to the next end of line, not stopping on those lines that have a period at the end.所以,我想做一个跳转到下一个行尾的宏,而不是停在那些末尾有句点的行上。

I used this regex:我使用了这个正则表达式:

[^\.\s][\s]*$

Meaning: find any character that is not a period nor a whitespace, optionally followed by whitespaces to the end of the line.含义:查找既不是句点也不是空格的任何字符,可选地后跟空格到行尾。

I would then apply the J command to join the matched line with the next one, and then repeat.然后我会应用J命令将匹配的行与下一行连接起来,然后重复。

It works fine on RegexPal , but in Vim it stops at lines that have a period and two spaces.它在RegexPal上运行良好,但在 Vim 中,它在有句号和两个空格的行处停止。

What am I doing wrong?我究竟做错了什么?

Instead of using the regex in a macro in conjunction with the J command, how about using a regex substitution to remove linebreaks?与其在宏中将正则表达式与J命令结合使用,不如使用正则表达式替换来删除换行符怎么样? This seems to work for me:这似乎对我有用:

:%s/[^\.]\s*\zs$\n\(^\s*$\n\)*/ /

Explanation:解释:

  • [^\.]\s*\zs$\n -- lines not ending with a period; [^\.]\s*\zs$\n -- 不以句点结尾的行; start the replacement before the linebreak.在换行符之前开始替换。
  • \(^\s*$\n\)* -- include any further lines containing only whitespace \(^\s*$\n\)* -- 包括仅包含空格的任何其他行

This regex is then replaced with a space.然后将此正则表达式替换为空格。

If the cursor is located at the first line of a paragraph, one can join its lines with如果光标位于段落的第一行,可以用

:,/\.\s*$/j

To do the same for all paragraphs in a buffer, use the command要对缓冲区中的所有段落执行相同操作,请使用命令

:g/^/,/\.\s*$/j

This should get you part way there: use shime 's regexp ( \.\s*$ ) to identify lines you want to join, then use :v//j!这应该让你走到那里:使用shime的正则表达式( \.\s*$ )来识别你想要加入的行,然后使用:v//j! to join each such line to the next line.将每一行连接到下一行。

Then repeat the :v//j!然后重复:v//j! command until done.命令直到完成。 (Define a macro to do it: :map v:v//j!<cr> then just hit v repeatedly.) (定义一个宏来完成它:map v:v//j!<cr>然后重复点击v 。)

A better solution, if you're on a *NIX-like machine is:如果您使用的是类似 *NIX 的机器,则更好的解决方案是:

awk '/\.\s*$/ { printf("%s\n", $0);} { printf("%s", $0); } END { printf("\n"); }' <your_file >your_other_file

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM