【问题标题】:Equivalent to Vim's regex start and end match (`\zs` and `\ze`)?相当于 Vim 的正则表达式开始和结束匹配(`\zs` 和 `\ze`)?
【发布时间】:2015-05-21 22:47:12
【问题描述】:

如果我只想用 Atom 中的其他内容替换匹配项的一部分,我该怎么做?

Ruby 正则表达式解决方案可能会起作用,因为 Ruby 使用的正则表达式引擎与 Oniguruma(Atom 使用的)非常相似。

我找到了一个Oniguruma manual,上面写着\G 设置了比赛开始位置,但这对我不起作用。

【问题讨论】:

  • ruby 中的匹配开始是:\G
  • 谢谢。不幸的是,它不适用于 Atom。

标签: ruby regex atom-editor oniguruma


【解决方案1】:

我认为 Ruby 没有直接等效于 \zs\ze,但您可以使用前瞻((?=pat)) 和后瞻((?<=pat)) 来模仿它们的行为:

[1] pry(main)> ('abc'.match /(?<=a)b(?=c)/)
=> #<MatchData "b">
[2] pry(main)> ('bc'.match /(?<=a)b(?=c)/)
=> nil
[3] pry(main)> ('ab'.match /(?<=a)b(?=c)/)
=> nil

不幸的是,Ruby 的lookbehind 需要固定大小的模式(或几个固定大小的替代方案)——Vim 的\zs 没有这个限制。

【讨论】:

    【解决方案2】:

    Ruby 曾经使用Oniguruma 作为正则表达式引擎,但后来它从 Ruby 2.0 切换到 Onigmo(Oniguruma 的一个分支)。 Onigmo 支持几种新的构造,例如条件构造和例程调用(允许您编写递归正则表达式)。

    直接等效于\zs\K,仅在Onigmo 中支持。注意\K 和look-behind 是不等价的。

    为了演示其中一种情况,给定字符串aaaa

    • a\Ka 从索引 1、3 开始有 2 个匹配项,但是当引擎在索引 0 和 2 处执行搜索时会找到这些匹配项。
    • (?&lt;=a)a 从索引 1、2、3 开始有 3 个匹配项。

    区别在于\K(或\zs)只修改了组0的起始索引(整个表达式匹配的文本)。引擎开始搜索下一个匹配的位置与剥离所有\K时相同的模式相同。

    没有直接等效于\ze。但是,对于\ze 不在任何组内的简单情况,您可以通过使用前瞻来模拟行为,如Idan Arye's answer 所示。 \ze 与前瞻非常相似,因为引擎根据\ze 设置的结束索引而不是\ze 之后的模式到达的索引来搜索下一个匹配项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 2022-07-05
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      • 2013-12-27
      • 2020-04-03
      相关资源
      最近更新 更多