搜索到的模式可以包含在正则表达式(Vim)中吗?

发布于 2025-01-08 10:37:13 字数 1178 浏览 1 评论 0原文

我对正则表达式非常陌生,我需要一些帮助。首先,我将解释我的动机和一些图表,因为否则很难解释。

我最近安装了 Vim 缩进指南,它像这样显示那些垂直条/标尺(图片来自github 帐户):

Vertical Bars

其实现方式是通过模式匹配行开头的空格并添加将它们设置为 IndentGuidesEvenIndentGuidesOdd。这样做的问题是它无法模式匹配空行,并且您得到的高亮效果不太理想,如下所示: Poorhighlighting

最简单的解决方案是删除所有空/空白行,但没有空格的代码可以很难读。我的想法是分几个阶段转换代码,并最终添加空格,如下所示。

Animation

我正在做的是:

  • 从所有只有空格的行中删除空格 %s/\s\+$ //e
  • 截断所有多个空行 %s/\n\{3,}/\r\r/e
  • 向空行添加空格 %s/^\ \ (\ *\)\([^\ ]\)\(.*\)\n^\ *$\n^\ /\ \1\2\3\r\ \1\r\ /gc

最后一条语句的作用是查看三个其中第一行和第三行非空,第二行为空。但是,如果第一行缩进 8 次,而第三行仅缩进 3 次,就会出现问题。无论如何,在找到第一个模式(在本例中为 8 个缩进)后,是否可以在相同的搜索模式中使用它来确保第 1 行和第 3 行以相同数量的空格开头?我确信我可以使用迭代函数来完成此操作,例如从 30 个缩进开始,然后返回,但这可能有点低效。

我知道只有空格的行是不好的。然而,删除空格是微不足道的,我已经映射了键来自动执行此操作。如果需要的话我可以快速删除它们。另外,我知道问题比这更复杂,并且有更多的情况需要考虑,但是,我会按情况处理这些情况。

关于我如何去做这件事有什么建议吗?

I am very new to regular expressions, and I need some help. First I will explain my motivation and some diagrams, as it is very hard to explain otherwise.

I recently installed Vim Indent guides which displays those vertical bars/rulers like so (picture from github account):

Vertical Bars

The way it does this is by pattern matching spaces at the beginning of a line and adding them to either the IndentGuidesEven or the IndentGuidesOdd. The problem with this is that it can't pattern match empty lines, and you get less than ideal hilighting like so:
Poor highlighting

The easiest solution is to remove all empty/blank lines, but code without spaces can be hard to read. What I had in mind is to transform the code in several stages, and ultimately adding spaces, as shown below.

Animation

What I am doing is:

  • removing spaces from all lines with only spaces %s/\s\+$//e
  • truncating all multiple empty lines %s/\n\{3,}/\r\r/e
  • adding spaces to empty lines %s/^\ \(\ *\)\([^\ ]\)\(.*\)\n^\ *$\n^\ /\ \1\2\3\r\ \1\r\ /gc

what that last statement does is look at three lines where the first and third non empty and the second one is empty. But this leads to problems if the first line is, for example indented in 8 times and the third one is only indented in 3 times. Is there anyway, upon finding the first pattern (in this case 8 indents) to use it in the same search pattern to make sure lines 1 and 3 start with the same number of spaces? I'm sure I could do this with an iterative function, and start from, for example 30 indents, and work my way back, but that might be a little inefficient.

I am aware that lines with only spaces are bad. However, removing spaces is trivial and I have key mapped to do this automatically. If need be I can quickly remove them. Also, I know the problem is more complex than this, and there are more cases to consider, however, I will deal with those cases as they present themselves.

Any advice as to how I could go about doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静水深流 2025-01-15 10:37:13

为了根据您最后的评论实施第三步,可以
使用以下命令。

:%s/^$/\=repeat(' ',min([indent(line('.')-1),indent(line('.')+1)]))

这种全局替换依赖于具有表达式特征的替换
(参见 :help sub-replace-\=)用包含的字符串替换空行
重复空格字符 min([indent(line('.')-1),indent(line('.')+1)])
次。空格数计算为连接的两个值中的最小值
在临时列表中。这些值是行的缩进级别
紧邻当前行的前后 (​​line('.') 计算结果为
它的数量);缩进级别是使用 indent() 确定的
功能。

In order to implement the third step according to your last comment, one can
use the following command.

:%s/^$/\=repeat(' ',min([indent(line('.')-1),indent(line('.')+1)]))

This global substitution relies on the substitute with an expression feature
(see :help sub-replace-\=) to replace empty lines with a string containing
a space character repeated min([indent(line('.')-1),indent(line('.')+1)])
times. The number of spaces is calculated as a minimum of two values joined
in a temporary list. These values are indentation levels of the lines
immediately preceding and succeeding the current one (line('.') evaluates to
its number); the levels of indent are determined using the indent()
function.

待天淡蓝洁白时 2025-01-15 10:37:13

使用 vim 填充空格:

:g/^$/s//\=printf('%*s', strlen(matchstr(getline(line('.')-1), '^\s*')),'')

或者

:g/^$/s//\=matchstr(getline(line('.')-1), '^\s*')

use vim to fill white spaces:

:g/^$/s//\=printf('%*s', strlen(matchstr(getline(line('.')-1), '^\s*')),'')

Or

:g/^$/s//\=matchstr(getline(line('.')-1), '^\s*')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文