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

Regex 如何使用正则表达式将换行转换为缩进,regex,vim,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 我在vi

我有一个类似以下内容的列表:

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解决方案都适合我

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

tr '\n' '\t'

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

tr '\n' '\t'

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

tr '\n' '\t'

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

tr '\n' '\t'

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

(?<!\n)\n\t*\n
(?
递归查找并替换此正则表达式的所有匹配项

  • 首次通过替换为:\n
  • 第二遍替换为:\n\t
  • 第三遍替换为:\n\t\t
  • 第四遍替换为:\n\t\t\t
…等等,直到任何地方都找不到正则表达式的匹配项


因此,您不必每次都运行不同的正则表达式,但仍然需要更改replace with part。您可以编写一个小程序来递归地执行此操作。

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

(?<!\n)\n\t*\n
(?
递归查找并替换此正则表达式的所有匹配项

  • 首次通过替换为:\n
  • 第二遍替换为:\n\t
  • 第三遍替换为:\n\t\t
  • 第四遍替换为:\n\t\t\t
…等等,直到任何地方都找不到正则表达式的匹配项


因此,您不必每次都运行不同的正则表达式,但仍然需要更改replace with part。您可以编写一个小程序来递归地执行此操作。

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

(?<!\n)\n\t*\n
(?
递归查找并替换此正则表达式的所有匹配项

  • 首次通过替换为:\n
  • 第二遍替换为:\n\t
  • 第三遍替换为:\n\t\t
  • 第四遍替换为:\n\t\t\t
…等等,直到任何地方都找不到正则表达式的匹配项


因此,您不必每次都运行不同的正则表达式,但仍然需要更改replace with part。您可以编写一个小程序来递归地执行此操作。

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

(?<!\n)\n\t*\n
(?
递归查找并替换此正则表达式的所有匹配项

  • 首次通过替换为:\n
  • 第二遍替换为:\n\t
  • 第三遍替换为:\n\t\t
  • 第四遍替换为:\n\t\t\t
…等等,直到任何地方都找不到正则表达式的匹配项

因此,您不必每次都运行不同的正则表达式,但仍然需要将replace改为part。您可以编写一个小程序来递归地执行此操作。

Perl方法:

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

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

Item 1
        Subitem 1
Item 2
Item 3
        Subitem 1
        Subitem 2
                Subsubitem 1
Item 4
Perl方法:

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

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

Item 1
        Subitem 1
Item 2
Item 3
        Subitem 1
        Subitem 2
                Subsubitem 1
Item 4
Perl方法:

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

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

Item 1
        Subitem 1
Item 2
Item 3
        Subitem 1
        Subitem 2
                Subsubitem 1
Item 4
Perl方法:

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

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

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

这可以通过
:s
和子替换表达式(
\=
)实现

基本上,我们计算
\n
的数量,并将其替换为相同数量的
\t

  • :%s/^\n\+/…/g
    查找我们的
    \n
    序列
  • %s/../\={expr}/g
    将匹配替换为表达式的求值,
    {expr}
  • 子匹配(0)
    获取第n个子匹配。与本例中的
    \0
    &
    相同
  • repeat({str},{num})
    返回一个字符串,
    {str}
    重复
    {num}
  • len({str})
    获取字符串的长度,
    {str}
  • len(子匹配(0))-1
    减小长度,因为我们希望在单独的行上保留“好行”
有关更多帮助,请参阅:

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

这可以通过
:s
和子替换表达式(
\=
)实现

基本上,我们计算
\n
的数量,并将其替换为相同数量的
\t

  • :%s/^\n\+/…/g
    查找我们的
    \n
    序列
  • %s/../\={expr}/g
    将匹配替换为表达式的求值,
    {expr}
  • 子匹配(0)
    获取第n个子匹配。与本例中的
    \0
    &
    相同
  • repeat({str},{num})
    返回一个字符串,
    {str}
    重复
    {num}
  • len({str})
    获取字符串的长度,
    {str}
  • len(子匹配(0))-1
    减小长度,因为我们希望在单独的行上保留“好行”
有关更多帮助,请参阅:

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

这可以通过
:s
和子替换表达式(
\=
)实现

基本上,我们计算
\n
的数量,并将其替换为相同数量的
\t

  • :%s/^\n\+/…/g
    查找我们的
    \n
    序列
  • %s/../\={expr}/g
    将匹配替换为