如何使用正则表达式将换行符转换为缩进

时间:2015-07-07 19:03:14

标签: regex vim

我的列表看起来像这样:

Item 1


Subitem 1

Item 2

Item 3


Subitem 1


Subitem 2



Subsubitem 1

Item 4

实际上,每个顶级项目前面都有一个换行符,每个子项目有两个换行符,子子项目有三个,依此类推。我希望它的格式类似于:

Item 1
    Subitem 1
Item 2
Item 3
    Subitem 1
    Subitem 2
        Subsubitem 1
Item 4

我在vim中使用的正则表达式是:

第一级:

%s/^$\n\(\t\w\)/\t\1/g

第二级:

%s/^$\n\(\t\t\w\)/\t\1/g

等等。

如果不必为列表的每个级别运行不同的正则表达式,更好的方法是什么?我尝试使用vim来做这件事,但任何* nix解决方案对我都没问题。

4 个答案:

答案 0 :(得分:1)

这取决于执行正则表达式的内容。 例如。 Sed解析行时不会做的伎俩。如果您使用的是sed,请尝试将其替换为tr:

tr '\n' '\t'

答案 1 :(得分:1)

Perl方式:

input{
   file{
     path =>"path/to/system1_log_file"
     type =>"sys1logs"
   }

  file{
    path =>"path/to/system2_log_files"
    type =>"sys2logs"
  }
}

output{
  if[type]=="sys1logs"{
  #output to sys1 index
   elasticsearch{host => localhost
               index => "sys1"
               }
   }

 if[type]=="sys2logs"{
 #output to sys2 index
  elasticsearch{host => localhost
               index =>"sys2"
              }
  }
}

使用perl -0777pe 's/\n\K\n+/"\t"x(-1+length $&)/gse' 和GNU tr

sed

输出:

tr '\n' '\t' | sed -E 's/([^\t])\t\t/\1\n/g'

答案 2 :(得分:1)

这可以通过:s和sub-replace-expression(\=)完成。

:%s/^\n\+/\=repeat("\t",len(submatch(0))-1)/

基本上我们会计算\n的数量,并用\t的相同数量替换它们。

  • :%s/^\n\+/.../g找到\n的序列
  • %s/.../\={expr}/g将匹配替换为表达式{expr}
  • 的评估
  • submatch(0)获得第n个子匹配。在这种情况下与\0&相同。
  • repeat({str}, {num})返回一个字符串,{str}重复{num}次。
  • len({str})获取字符串长度{str}
  • len(submatch(0))-1减少长度,因为我们希望将“好线”保持在不同的行上。

如需更多帮助,请参阅:

:h :s
:h sub-replace-expression
:h :repeat()
:h :len()
:h submatch()

答案 3 :(得分:0)

您可以做的一件事是递归使用以下正则表达式:

(?<!\n)\n\t*\n

递归查找并替换此正则表达式的所有匹配项

  • 首次通过替换为:\ n
  • 第二遍替换为:\ n \ t
  • 第三遍替换为:\ n \ t \ t
  • 第四遍替换为:\ n \ t \ t \ t

......依此类推,直到正则表达式无处可匹配。

因此,您不必每次都运行不同的正则表达式,但您仍然需要更改部分替换。你可以编写一个小程序来递归地执行它。