用正则表达式替换Vim

时间:2012-11-02 18:41:53

标签: regex vim substitution

正则表达式的新手,我需要在某些日期模式匹配以更改格式。

我要从mm/dd/yy转到yyyy-mm-dd,那里2000之前没有参赛作品。

我不熟悉的是如何将内容分组以使用各自对\1\2等的引用。

我是否首先希望mm/dd/yy上的内容与( \d{2} ) ( \/\d{2} ) ( \/\d{2} )匹配,还是像\d\d/\d\d/\d\d一样简单?

假设我的第一个分组部分是正确的想法,我希望做的事情如下:

:%s/old/new/g
:%s/ ( \d{2} ) ( \/\d{2} ) ( \/\d{2} ) / ( 20+\3) - (\3) - (\1) /g

编辑:抱歉,替换是带有​​连字符的yyyy-mm-dd format,而不是斜线。

4 个答案:

答案 0 :(得分:9)

我打算对另一个答案发表评论,但这很复杂。

注意magic设置。如果您希望未转义的parens进行分组,则需要在模式中的某处包含\v。 (见:help magic)。

如果在:s命令中使用斜杠以外的其他内容,则可以避免转义斜杠。

你很亲密。 :)你不想要所有这些空格,因为他们需要在相同的地方匹配空格。

我的解决方案,我使用\v所以我不需要逃避parens和感叹号所以我可以在我的模式中使用斜杠而不会逃避它们:

:%s!\v(\d{2})/(\d{2})/(\d{2})!20\3-\2-\1!g

这将匹配以三个或更多数字开头或结尾的“内部”项目。如果你能给出开始/结束标准,那么这可能会有所帮助。假设简单的“单词边界”条件有效,您可以使用<>

:%s!\v<(\d{2})/(\d{2})/(\d{2})>!20\3-\2-\1!g

专门批评你(学习!):

:%s/ ( \d{2} ) ( \/\d{2} ) ( \/\d{2} ) / ( 20+\3) - (\3) - (\1) /g
  • 摆脱空间,因为大概你不想要它们!
  • 您的分组需要\( \)\v才能正常工作
  • 除非您使用\{2}
  • ,否则您还需要\v
  • 您将斜杠放在第二组和第三组中,这意味着它们也会出现在替换中
  • 您不希望输出中有括号!
  • 你直接替换文字;你不希望输出中的20之后的+

答案 1 :(得分:1)

试试这个:

:%s/\(\d\{2}\)\/\(\d\{2}\)\/\(\d\{2}\)/20\3-\2-\1/g

您感兴趣的位是:\(...\) - 捕获; \d - 一个数字; \{N} - N次出现;和\/ - 字面正斜杠。

所以它捕获两个数字,跳过一个斜线,捕获另外两个,跳过另一个斜线,再捕获两个,然后将其替换为“20”+第三个对联+“ - ”+第二个对联+“ - ”+第一对联。这应该将“dd / mm / yy”变成“20yy-mm-dd”。

答案 2 :(得分:1)

好的,试试这个:

 :0,$s#\(\d\{1,2\}\)/\(\d\{1,2\}\)/\(\d\{1,2\}\)#20\3-\2-\1#g

我已经删除了匹配部分和替换部分中的大量空间以及大部分的空白,因为您要求的格式没有。

有些注意事项:

  • 使用vi,您可以更改&#39; /&#39;任何其他角色,当你尝试将字符串与斜线匹配时,它会有所帮助。我通常使用&#39;#&#39;但它并非必须如此。
  • 你必须逃脱parens和花括号
  • 我使用:0,$而不是%s,但我认为它具有相同的含义 - 将以下命令应用于第0行和结尾之间的每一行。

答案 3 :(得分:-1)

对于比赛:(\d{2})\/(\d{2})\/(\d{2})

对于替换:20\3\/\1\/\2