###############################################################################
# Trackpad, mouse, keyboard, Bluetooth accessories, and input #
###############################################################################
# Trackpad: enable tap to click for this user and for the login screen
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
我想用
# Trackpad: ...
替换running "Trackpad: ..."
解决问题,我想出了一些使用一个正则表达式测试器:
/\n\n#\s(.*)/g
如果我在Vim中尝试使用它,对我不起作用:
:/\n\n#\s(.*)/running ""/g
我想我的问题可以归结为两个具体问题:
如何避免搜索
\n
字符,而是确保#
不会出现在搜索组?如何有效使用捕获组?
下面有一些很好的答案。很难在这三者之间进行选择,但是我认为所选的答案对于我的原始规格而言是最准确的。我建议您尝试使用实际文件中的所有三个答案,以了解您的感受。
#1 楼
只是要清楚……我相信您要求这是替换的结果?###############################################################################
# Trackpad, mouse, keyboard, Bluetooth accessories, and input #
###############################################################################
running "Trackpad: enable tap to click for this user and for the login screen"
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
在这种情况下,我建议使用以下命令:
:%s/\n\n#\s\+\(.*\)/^M^Mrunning ""/
模式的解释
:s/PATTERN/REPLACEMENT/
是替代命令。 :%s
中的百分号使它适用于整个文件,而不是仅适用于当前行。\n\n
表示关注行必须出现在空白行之后。如果您不关心前面的空白行,那么^
就足够了。 #\s\+
捕获该行上的所有后续文本。替换文本的说明
\(.*\)
插入行的两端以替换模式中存在的^M^M
。否则,文本将移动到空白行之前的行末。要键入每个\n\n
,请按Ctrl-V Ctrl-M。,然后插入字符串
^M
,然后在双引号内的括号中捕获任何内容。#2 楼
我会用类似的东西::s/^#\s\+\(.\{-}\):/running "":/
^#
匹配锚定在行首的#
字符(这回答了问题1) \s\+
一次或多次匹配任何空白\(
发起一个分组(这将回答问题2).\{-}\
匹配任何字符0或更多次以非贪婪的方式;这与.*
不同,因为它尝试匹配的越少越好。尝试在注释中添加一个:
字符,以了解为什么这很重要\)
结束该子组。:
匹配文字:
然后将其替换为所需的文本,并使用
引用捕获的组。我使用正则表达式测试器提出了一些建议
正则表达式语法有点像Wiki语法:一堆,它们乍一看都很相似,它们显然都不比其他任何一个都要好,但是有很多区别。
今天,所谓的“ Perl兼容”正则表达式在大多数语言中都是默认设置,但是Vim正则表达式与Perl兼容表达式不兼容!当Perl不在时,Vim regexp语法至少可以追溯到70年代。
您可以在子组中看到这一点,您必须在其中使用
\(
而不是(
(这与POSIX“基本”语法,但不包含更常见的POSIX“扩展”语法或Perl语法)。您可以通过在模式中添加\v
标志来控制此操作(有关详细信息,请参见:help /\v
),这将使其变得“更兼容”,但不能完全兼容(例如,对于非贪婪匹配,您仍必须使用.{-}
)因此,这也许可以解释为什么几乎可以使用“ regex测试仪”,但效果不佳。
http://www.vimregex.com/作为Vim regexp的良好概述/备忘单。
评论
很好的答案,尤其是为什么使用正则表达式!=正则表达式。至于您的搜索和替换,由于注释中可能带有或不带有:,所以有些棘手。有关详细信息,请参见完整文件github.com/squarefrog/dotfiles/blob/master/osx/…
–squarefrog
15年4月29日在10:36
#3 楼
您可以:搜索不以
#
结尾的行::/[^#]$/
在行首替换
#\s(.*)
:s/\v^#\s(.*)/running ""/
要使用组,您需要:
转义括号,使其成为正则表达式语法的一部分:
\(.*\)
,或者使用“魔术”通过以
\v
开头表达式:s/\v...
将其组合:
:/[^#]$/s/\v^#\s(.*)/running ""/
评论
这非常出色,感谢您对标签的含义进行了解释,而不仅仅是我需要编写的文本。
–squarefrog
2015年4月29日在10:21
感谢您明确表示方括号必须转义才能成为regex语法的一部分。正则表达式组在使它们正常工作方面始终遇到问题。
–阿达马
19年8月5日在9:24
评论
我无法编辑您的答案,但我相信您的意思是:%s / \ v \ n \ n#\ s +(。*)/ ^ M ^正在运行“ \ 1” /(添加了“ magic”标志)。很难为我的原始问题选择正确的答案,但是我觉得这个答案最接近我的原始预期答案。它也是唯一可在整个文件中使用而无需选择范围的文件。
–squarefrog
2015年4月30日7:31
IIRC您可以使用\ r而不是^ M来获得新行?
–muru
15年4月30日在8:18