【问题标题】:Using regex backreference after matching n times匹配 n 次后使用正则表达式反向引用
【发布时间】:2018-08-23 14:52:35
【问题描述】:

我需要匹配 puppet 定义中的几个字符串:

  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh1':  value => '4096' }
  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh2':  value => '8192' }
  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh3':  value => '16384' }
  sysctl::conf { 'net.ipv6.conf.all.disable_ipv6':     value => '0' }
  sysctl::conf { 'net.ipv6.conf.default.disable_ipv6': value => '0' }

然后使用反向引用添加相同的行再加上一行以这样结束:

  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh1':  value => '4096' }
  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh2':  value => '8192' }
  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh3':  value => '16384' }
  sysctl::conf { 'net.ipv6.conf.all.disable_ipv6':     value => '0' }
  sysctl::conf { 'net.ipv6.conf.default.disable_ipv6': value => '0' }
  sysctl::conf { 'net.ipv4.tcp_mtu_probing': value       => '1' }

我试过这个匹配模式( sysctl::conf \{.*\}\n{1,}),然后用\1\n sysctl::conf { 'net.ipv4.tcp_mtu_probing': value => '1' }替换它

问题是反向引用是引用每一行而不是所有分组块以在末尾添加我的新行。这是我得到的,而不是期望的结果:

  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh1':  value => '4096' }
  sysctl::conf { 'net.ipv4.tcp_mtu_probing': value       => '1' }
  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh2':  value => '8192' }
  sysctl::conf { 'net.ipv4.tcp_mtu_probing': value       => '1' }
  sysctl::conf { 'net.ipv4.neigh.default.gc_thresh3':  value => '16384' }
  sysctl::conf { 'net.ipv4.tcp_mtu_probing': value       => '1' }
  sysctl::conf { 'net.ipv6.conf.all.disable_ipv6':     value => '0' }
  sysctl::conf { 'net.ipv4.tcp_mtu_probing': value       => '1' }
  sysctl::conf { 'net.ipv6.conf.default.disable_ipv6': value => '0' }
  sysctl::conf { 'net.ipv4.tcp_mtu_probing': value       => '1' }

我应该尝试将整个行块匹配为一个模式而不是同一模式的多个匹配吗?

我这样做是因为我正在使用 Atom 搜索和替换多个文件中的所有 sysctl::conf 条目,这些条目不相同,并在已经存在的条目之后添加新条目。

谢谢你:)

PS:已经知道在 atom 中反向引用被称为 $1 而不是 \1。

【问题讨论】:

    标签: regex atom-editor regex-group


    【解决方案1】:

    你可以试试这个模式

    (?:\s*sysctl::conf \{.*\})+
    

    之后替换为

    \0\n  sysctl::conf { 'net.ipv4.tcp_mtu_probing': value       => '1' }
    

    注意\0,因为没有任何捕获组。

    解释:

    • ?: 是一个非捕获组,用于捕获孔块(即\0)。
    • \s* 匹配任何空白字符(等于 [\r\n\t\f\v ])。
    • + 最后捕获所有匹配项。

    【讨论】:

    • 它在 vim 和 Atom 中都对我不起作用。它确实匹配整个块,但反向引用只是替换它的最后一行:(
    • 你是对的。使用 Vim 你应该写::%s/\%(\s*sysctl::conf {.*}\n\)\+/\0 sysctl::conf { 'net.ipv4.tcp_mtu_probing': value => '1' }/g。请让我知道它是否有效。
    • 太棒了!效果很好!非常感谢你,米格尔 :)
    • 很高兴我能帮上忙 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2013-10-04
    相关资源
    最近更新 更多