3

在一些 html 编辑的基础上,我想出了需要一些 VIM 大师的帮助。

我不想完成简单的任务 - 我有带有损坏 url 的 html 文件。

<a href="http://some/wrong/url with variable number of spaces">Just description</a> <a href="http://some/wrong/url with three spaces">Just description</a>
...
<a href="http://anoter/wrong/url with completely other number of spaces">Just description</a>

不幸的是,它不是“每行一个 url”。

我知道三种方法:

  1. 我希望只能在'"http://[^"]*"'正则表达式中替换(类似于仅在匹配行中替换 - 但这次不是整行,而是应该只涉及匹配模式)

  2. 或者使用类似 sed 的标签——我可以用 sed -e 来完成这个任务:a -e's#\("http://[^" ]*\) \([^"]*"\)#\1_\2#g;ta'

  3. 我也知道有类似的东西,"\@<="但我不是母语人士,这方面的 vim 手册超出了我的理解范围。

非常感谢所有帮助。

如果可能的话,我想知道所有三个问题的答案(因为这些问题非常有趣并且对其他任务有帮助),但其中任何一个都可以。

4

2 回答 2

3

回复: 1.您可以通过将 vim 的“将替换评估为表达式”功能 ( :h :s\=) 与substitute函数 ( :h substitute()) 组合来递归替换:

:%s!"http://[^"]*"!\=substitute(submatch(0), ' ', '_', 'g')!g

回复:2。我不知道sed,所以我无法帮助你。

回复: 3. 我不知道\@<=在这里有什么帮助。至于它的作用:相当于Perl的(?<=...)特性,也称为“正向后视”。您可以将其理解为“如果在前面”:

:%s/\%(foo\)\@<=bar/X/g

“如果它前面是”,则替换bar为,即把每个变成(这里只是为了分组)。在 Perl 中,你可以这样写:XfoofoobarfooX\%( ... \)

s/(?<=foo)bar/X/g;

更多示例和解释可以在 中找到perldoc perlretut

于 2013-01-14T12:13:37.113 回答
1

我认为您想要做的是将 http:// url 中的所有空格替换为_.

为了实现这个目标,@melpomene 的解决方案很简单。你可以在你的vim中试试。

另一方面,如果你想模拟你的 sed 线,你可以尝试以下。

:let @s=':%s#\("http://[^" ]*\)\@<= #_#g^M'

^M means Ctrl-V then Enter

然后

200@s

这与您的 sed 行(标签、替换、返回标签...)的工作方式相同,并且@<=也被使用过。

一个问题是,通过这种方式,vim 无法检测到所有匹配模式何时被替换。因此给出了一个相对较大的数字(在我的示例中为 200)。最后显示错误消息“E486:未找到模式...”。

需要一个脚本来避免该消息。

于 2013-01-14T14:07:37.163 回答