Regex 使用vim替换出现次数可变的不匹配字符串
我希望使用vim仅从包含以下示例文本的文件中提取方括号和其中的数字:Regex 使用vim替换出现次数可变的不匹配字符串,regex,vim,replace,Regex,Vim,Replace,我希望使用vim仅从包含以下示例文本的文件中提取方括号和其中的数字: 13_[4]_3_[4]_[1]_5_[1]_29_[3]_4_[2]_9_[1]_6_[2]_4 14_[4]_28_[3]_4_[2]_12_[1]_8_[2]_2 [1]_[4]_15_[1]_16_[3]_4_[2]_11_[1]_16_[2]_2 9_[4]_3_[4]_3_[4]_9_[4]_4_[4]_7_[1]_12_[3]_4_[2]_9_[1]_[2]_2 14_[4]_30_[3]_4_[2]_5_[1]
13_[4]_3_[4]_[1]_5_[1]_29_[3]_4_[2]_9_[1]_6_[2]_4
14_[4]_28_[3]_4_[2]_12_[1]_8_[2]_2
[1]_[4]_15_[1]_16_[3]_4_[2]_11_[1]_16_[2]_2
9_[4]_3_[4]_3_[4]_9_[4]_4_[4]_7_[1]_12_[3]_4_[2]_9_[1]_[2]_2
14_[4]_30_[3]_4_[2]_5_[1]_19_[1]_3_[1]_8_[2]_10_[1]_4_[1]_3_[1]_2
因此,对于第一个示例行,我希望输出行如下所示:
[4] [4][1][1][3][2][1][2]
我可以用以下方法轻松删除方括号:
:%s/\[\d\]//g
但是我很难删除所有不匹配的文本[/d]。大多数使用否定(例如:v)的vim命令似乎只在整行而不是单个字符串上运行,并且使用%s进行组匹配:
:%s/\v(.*)([\d])(.*)/\2
还匹配并删除方括号
有人能给我一个解决问题的建议吗 你很接近。您需要引用方括号,并使用比
*
更不贪婪的内容
:%s/\v[^[]*(\[\d\])[^[]*/\1/g
概述
匹配前导文本+[
+数字+]
+尾随文本。捕获[
+数字+]
。替换与捕获组匹配的。只留下括号和数字
细节的荣耀
- 使用
非常神奇。请参见\v
:h magic
是一个括号内的字符类,它匹配其中的任何字符。e、 g.[…]
匹配fooba[rs]
和foobar
,但不匹配foobas
。请参阅foobaz
(注意,Vim可能将其称为集合。):h/\[
是一个用括号括起来的否定字符类,因此不匹配括号内的任何字符。例如,[^…]
匹配fooba[^rz]
,但不匹配foobas
和foobaz
foobar
-匹配任何非[^[]
字符。(这看起来很有趣)[
-匹配为非[^[]*
字符零次或多次。这将匹配我们要删除的前导文本[
-捕获组(…)
&\[
表示文字\]
/[
。我们必须转义以防止字符类]
匹配1位数字\d
-匹配要删除的尾随文本[^[]*
替换的将是我们的捕获组,即括号中的数字\1
- 使用
标志全局或更明确地多次执行此操作g
- 使用范围
对整个文件%
执行替换1,$
:s
:%s/\v(.*)([\d])(.*)/\2
会失败呢?
tl;dr:您的模式不匹配。请尝试/[\d]
长版本:
- 第一个
捕获的内容太多,只剩下最后一部分。例如,*
[2]…
创建一个括号内的字符类,该类与下列字符之一匹配:[\d]
或d
\
- 第二个
在使用*
标志时遇到与第一个相同的问题g
- 为什么不是3个捕获组呢?您当然可以有更多的捕获组,但在这种情况下它们是不必要的,所以请删除它们
- 缺少
标志。这意味着命令每行只进行一次替换,这将留下大量文本g
/
并按
或
调整搜索。或者更好地使用q/
打开命令行窗口因此,您可以像编辑任何文本一样编辑模式。您也可以在命令行上使用
(包括/
)打开命令行窗口
一旦有了模式,您就要开始替换。Vim提供了一个使用空模式使用当前搜索的快捷方式。例如:%s//\1/g
此技术尤其与set incsearch
和set hlsearch
相结合,意味着您可以在进行替换之前以交互方式查看匹配项。此技术将在下一集中显示:
需要学习更多的正则表达式语法吗?请参见:h模式
。这是一个非常长且密集的阅读过程,但在将来会对您有很大帮助。我还发现通过perldoc perlre
阅读Perl的正则表达式文档也是一个很好的地方。注意:Perl的正则表达式不同于Vim的正则表达式(请参见:h Perl模式
),但与Perl兼容的正则表达式(PCRE)非常常见
思想
你也可以考虑<代码> GRP-O < /代码>。例如<代码> %.GRP-O \ \ \\\\代码> < /P>
更多帮助
另一种方法是:
:%s/\v[^[]*(%(\[\d\])?)/\1/g
这真的很有帮助。对于[^[]
我一直认为第二个括号是配对的,这让我完全困惑。
:%s/\v[^[]*(%(\[\d\])?)/\1/g