正则表达式贪婪 : shrinking long path

标签 regex perl shell path sed

请看我的脑残粉

我一直坚持用正则表达式缩小一些很长的路径,就像这样:

/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890

我想将这条路径转换为以下形式:

/123/123/123/123/12/1/123/123/123/123

路径中的每个“目录”仅缩写为前 3 个字符

LONG_PATH="/12345/123456/1234/123/12/1/1234567/13245678/123456789/1234567890"
perl -pe "s#/(.{1,3})[^/]*?(/|$)#/\1\2#g" <<<$LONG_PATH

/123/123456/123/123/12//1234567/132/123456789/123

sed -E "s#/(.{1,3})[^/]*?(/|$)#/\1\2#g" <<<$LONG_PATH

/123/123456/123/123/12//1234567/132/123456789/123

我也试过:

perl -pe "s,/(.)(.)?(.)?[^/]*+,/\1\2\3,g" <<<$LONG_PATH
/123/123/123/123/12//123/132/123/123

还有很多其他的,没有“运气”——我仍然不知道。

请为我指明一条通往成功的正确道路。

最佳答案

最多匹配三个非斜杠字符并捕获它们。然后匹配其余的直到下一个斜线。替换为捕获:

"s#(/[^/]{3})[^/]*#\1#g"

这里不需要无礼之类的,因为取反的字符类与/$是互斥的。

编辑: 虽然您似乎知道这一点,但我应该向 future 的访问者澄清,这将适用于 perl -pe...sed - E... 正如您在问题中使用的那样。正则表达式也可以与 sed -r... 一起使用。如果您省略了 -E-r 选项,那么(像往常一样)您将需要转义圆括号和花括号:

sed "s#\(/[^/]\{3\}\)[^/]*#\1#g" filename

另请注意,ikegami 指出,在 Perl 中,您应该在替换中使用 $1 而不是 \1

关于正则表达式贪婪 : shrinking long path,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13334967/

相关文章:

Php/Perl/Python/Shell 脚本根据某些字符的存在来重命名文件

python - 执行 "from tkinter import *"后为什么 ttk 没有定义?

shell - 在文件中查找和替换并覆盖文件不起作用,它会清空文件

shell - `for NAME do ...` 中的 NAME 后是否禁止使用分号?

javascript - 正则表达式允许 9 个数字但阻止超过 4 个重复数字

Python 2.6 正则表达式机制?

c# - 获取 "-"之前所有字符的正则表达式

python - 正则表达式 : matching integers inside of brackets

linux - 磁盘故障检测perl脚本

perl - 使用perl获取AD组的用户