Regex 替换字符的奇数长度子字符串

Regex 替换字符的奇数长度子字符串,regex,vim,emacs,Regex,Vim,Emacs,我正在努力解决一个关于正则表达式的小问题 我想用另一个长度相同但字符不同的子字符串替换特定字符的所有奇数长度子字符串。 指定字符的所有偶数序列应保持不变 简化示例:字符串包含字母A、b和y,y的所有奇数长度序列应替换为z: abyyyab -> abzzzab 另一个可能的例子可能是: ycyayybybcyyyyycyybyyyyyyy 变成 zczayybzbczzzzzcyybzzzzzzz 使用正则表达式匹配所有奇数长度的序列没有问题 不幸的是,我不知道如何将这些匹配的

我正在努力解决一个关于正则表达式的小问题

我想用另一个长度相同但字符不同的子字符串替换特定字符的所有奇数长度子字符串。 指定字符的所有偶数序列应保持不变

简化示例:字符串包含字母A、b和y,y的所有奇数长度序列应替换为z:

abyyyab -> abzzzab
另一个可能的例子可能是:

ycyayybybcyyyyycyybyyyyyyy   
变成

zczayybzbczzzzzcyybzzzzzzz
使用正则表达式匹配所有奇数长度的序列没有问题

不幸的是,我不知道如何将这些匹配的长度信息合并到替换字符串中。 我知道我必须以某种方式使用反向引用/捕获组,但即使在阅读了大量文档和堆栈溢出文章之后,我仍然不知道如何正确地处理这个问题

关于可能的正则表达式引擎,我主要使用Emacs或Vim


如果我忽略了一个没有复杂正则表达式的更简单的通用解决方案,例如一系列小而固定的简单搜索和替换命令,这也会有所帮助。

以下是我在vim中的做法:

:s/\vy@<!y(yy)*y@!/\=repeat('z', len(submatch(0)))/g

TL;DR,:s/foo/\=blah将foo替换为作为vimscript代码计算的blah。因此,我们正在评估的代码是重复'z',lensubmatch0,它只是为我们匹配的每个'y'在'z'上生成。

以下是我在vim中的实现方式:

:s/\vy@<!y(yy)*y@!/\=repeat('z', len(submatch(0)))/g

TL;DR,:s/foo/\=blah将foo替换为作为vimscript代码计算的blah。因此,我们正在评估的代码是重复'z',lensubmatch0,它只是为我们匹配的每个'y'在'z'上生成。

如果您有perldo,您也可以使用:%perldo s/y+/length$&%2?z x length$&:$&/gei如果您有perldo,您还可以使用:%perldo s/y+/length$&%2?z x长度$&:$&/geWe也用tr代替repeat:\=trsubmatch0,'y','z'。当然,如果MWE中的y和z不是字符而是字符串,那么它将不起作用。我们也使用tr而不是repeat:\=trsubmatch0,'y','z'。当然,如果来自MWE的y和z不是字符而是字符串,那么它将不起作用。