Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex vim正则表达式与方括号匹配不起作用_Regex_Vim - Fatal编程技术网

Regex vim正则表达式与方括号匹配不起作用

Regex vim正则表达式与方括号匹配不起作用,regex,vim,Regex,Vim,使用vim,我试图转换以下两行 output reg [1:0] abcd, output reg efgh, 进入 我用的是正则表达式 :%s/\voutput|reg|\s*|\[.*\]|,//g 但是,我得到的输出是 [1:0]abcd, efgh, 谢谢你的帮助!谢谢 试试这个 \v\[.*]\s+|output\s+|reg\s+ 我将在一条线上完成这项工作。您可以录制一个宏,以便在多行上自动执行该操作 这很有效(在结尾处查找4个字母): %s/^.*\regexp中

使用vim,我试图转换以下两行

  output reg [1:0] abcd,
  output reg efgh,
进入

我用的是正则表达式

:%s/\voutput|reg|\s*|\[.*\]|,//g
但是,我得到的输出是

[1:0]abcd,
efgh,
谢谢你的帮助!谢谢

试试这个

\v\[.*]\s+|output\s+|reg\s+
我将在一条线上完成这项工作。您可以录制一个宏,以便在多行上自动执行该操作

这很有效(在结尾处查找4个字母):


%s/^.*\regexp中的问题是您请求\s*的部分。这意味着“没有或有很多空白”。由于整个regexp是一个大的OR,那么Vim将开始使用您的字符串,直到它找到至少一个空格。当这种情况发生时,它将从或的开头开始匹配,然后再次重复该过程。因此,这意味着您尝试在\s*之后接收的任何表达式都将被忽略,因为\s*在找到一个空白字符之前,可以使用任意数量的表达式。要验证这一点,请注意,如果更改\s*的位置,将得到不同的结果,这将转换为仅删除\s*之前的表达式

我相信您真正想要的regexp是:

:%s/\voutput|reg|\s+|\[.*\]|,//g

表示要替换至少有空白的位置。这对我来说很好。

您的正则表达式不起作用的原因

看起来vim从左到右读取正则表达式,并尝试按顺序匹配联合体的每个部分

因此,
output | reg |\s*|\[.\]\124;,
永远不会到达
\[.\]
,因为空字符串匹配每个字符之间的
\s*
。因为vim regex引擎匹配了一些东西,所以它立即进行替换

如果您只是对
\s*
的并集重新排序,则正则表达式将按预期工作


因此,命令应该是
:%s/\voutput | reg | \[.\].\124;,|\ s*//g
:help模式给出了原因(尽管从之前接触到的不同可能性中猜测原因很有帮助:-)

1。模式是一个或多个分支,由“\\\”分隔。它匹配任何内容
与其中一个分支匹配的
。示例:“foo\| beep”匹配“foo”和
匹配“嘟嘟声”。
如果多个分支匹配,则使用第一个分支。

Vim的正则表达式匹配器是第一个匹配引擎。POSIX命令最左最长。纯粹主义者可能会争辩说,其他任何东西都不是正则表达式匹配器,而只是一个“模式匹配器”,这可能与vim称之为“模式”有关
sed
perl
是最左边最长的:

$ sed -r 's/output|reg|\s*|\[.*\]|,//g' @@
abcd
efgh
但是有了第一个匹配引擎,你必须做一些不同的事情。重新排序您的备选方案,它会起作用:

:%s/\voutput|reg|\[.*\]|,|\s*//g
\s*
替换为
\s+
会使其对订单不敏感:

:%s/\voutput|reg|\s+|\[.*\]|,//g
Vim的
g
标志似乎只替换第一个匹配分支的每次出现,然后重试,直到没有任何变化

只是为了完整和混乱

:%s/\v(reg|output|\s*|\[.*\]|,)*//

考虑到上面推导的规则,这在一瞬间对我来说是有意义的


(编辑:
gawk
s
gensub
nvi
s
extended
引擎显然也是最左最长的)

奇怪的结果。请尝试
s/*(\w+),/$1/g
(或者您如何在vim中引用捕获组)。我保留这个问题,因为我想了解问题中提到的regexp不起作用的原因。您可以将您的regex(
\voutput | reg | s*[.\\]\124;,
)插入一个类似于可视化的站点。@Rakraks,正则表达式在PCRE和类似的风格中工作得很好,例如为什么它在vim中不工作,我不知道。谢谢,我尝试了下面的方法,它工作得很好。但是,我仍然不明白为什么我在问题中使用的regexp不起作用s/\v[.]\s*| output | reg |,|\s*///gb因为我猜你在]之后有空格,而且你有一个前斜杠
$ perl -ple 's/output|reg|\s*|\[.*\]|,//g' @@
abcd
efgh
:%s/\voutput|reg|\[.*\]|,|\s*//g
:%s/\voutput|reg|\s+|\[.*\]|,//g
:%s/\v(reg|output|\s*|\[.*\]|,)*//
abcd,
efgh,
:%s/\v(reg|output|\s*|\[.*\]|,)*//g
abcd
efgh