【问题标题】:Is there a standard for context replacement?是否有上下文替换的标准?
【发布时间】:2016-07-17 21:58:40
【问题描述】:

在vi中,换行

哎呀

我运行命令:

.s/a*\|j/x/g

线变成了

xj

而不是预期的

xx

这是 vi 的错误吗? sed、gawk 和 nawk 的行为符合预期,例如:

% echo aaaj | awk '{gsub(/a*|j/,"x");print}'
xx

另外,如果我运行命令而不是上面的命令

.s/j\|a*/x/g

(“j”和“a*”交换),那么该行将按预期变为“xx”。

【问题讨论】:

  • 正则表达式有不同的风格,请参阅 vi 的文档以了解如何在那里实现正则表达式。
  • “查看文档”是 stackoverflow 中几乎所有问题的答案。显然,如果我能在文档中找到它,我就不会问了。
  • 理论上,它应该替换a*j,因为a*\|jj\|a* 的DFA 相同。你的问题很好。由于我的回答没有回答原始问题,因此我将其删除。
  • 很多人不寻找文档。如果你做到了,那么请在问题中说明它,避免额外的猜测。
  • 是否应该在 stackoverflow.com 上提出任何问题的每个人都说明是她/他做到了?

标签: regex vim vi


【解决方案1】:

这里的“问题”是a* 子模式,它是交替中的第一个分支可以匹配一个空字符串

当引擎找到aaa 时,a* 替代分支匹配三个as,substitute 将它们全部替换为x。然后,引擎尝试在 3 as + 1(参见 source code comments)之后的位置 再次匹配。

请注意,a* 始终匹配,“获胜”,j 永远不会匹配。这是因为优先顺序,第一个分支总是在 Vim 正则表达式中获胜。如果您替换aaaj jjj,它将变为xjx xjxjxj,因为该模式将在不匹配字符之前匹配每个位置。

正确的模式

当替换为正则表达式时,您通常不想匹配与模式不匹配的字符之间的所有空位置,因此,合乎逻辑的解决方案是使用+ 量词,即a\+\|j 模式

【讨论】:

    猜你喜欢
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 2017-04-08
    • 1970-01-01
    相关资源
    最近更新 更多