正则表达式,搜索和替换,直到某一点

Pyr*_*cal 4 regex perl lookbehind

问题

我有一个充满线条的文件

convert.these.dots.to.forward.slashes/but.leave.these.alone/i.mean.it
Run Code Online (Sandbox Code Playgroud)

我想搜索和替换我得到的

convert/these/dots/to/forward/slashes/but.leave.these.alone/i.mean.it
Run Code Online (Sandbox Code Playgroud)

的.转换为/直到第一个正斜杠

问题

如何编写正则表达式搜索并替换以解决我的问题?

试图解决方案

我尝试使用perl后面的外观,但是没有实现可变长度外观

$ echo "convert.these.dots.to.forward.slashes/but.leave.these.alone/i.mean.it" | perl -pe 's/(?<=[^\/]*)\./\//g'
Variable length lookbehind not implemented in regex m/(?<=[^/]*)\./ at -e line 1.
Run Code Online (Sandbox Code Playgroud)

解决方法

实现了可变长度的前瞻,因此您可以使用这个肮脏的技巧

$ echo "convert.these.dots.to.forward.slashes/but.leave.these.alone/i.mean.it" | rev | perl -pe 's/\.(?=[^\/]*$)/\//g' | rev
convert/these/dots/to/forward/slashes/but.leave.these.alone/i.mean.it
Run Code Online (Sandbox Code Playgroud)

有没有更直接的解决方案来解决这个问题?

Wis*_*guy 5

s/\G([^\/.]*)\./\1\//g
Run Code Online (Sandbox Code Playgroud)

\G是一个与前一个匹配结束时的点匹配的断言.这确保了每个连续的匹配紧跟在最后一个之后.

火柴:

\G          # start matching where the last match ended
([^\/.]*)   # capture until you encounter a "/" or a "."
\.          # the dot
Run Code Online (Sandbox Code Playgroud)

取代:

\1     # that interstitial text you captured
\/     # a slash
Run Code Online (Sandbox Code Playgroud)

用法:

echo "convert.these.dots.to.forward.slashes/but.leave.these.alone/i.mean.it" | perl -pe 's/\G([^\/.]*)\./\1\//g'

# yields: convert/these/dots/to/forward/slashes/but.leave.these.alone/i.mean.it
Run Code Online (Sandbox Code Playgroud)

或者,如果你是一个纯粹主义者,并且不想将被捕获的子模式添加回来 - 避免这可能更有效,但我不确定 - 你可以利用\K将"真实"匹配仅限于.,然后简单地替换为/.\K基本上"忘记"与此相匹配的内容,因此最终返回的最终比赛只是在之后发生的事情\K.

s/\G[^\/.]*\K\./\//g
Run Code Online (Sandbox Code Playgroud)

火柴:

\G        # start matching where the last match ended
[^\/.]*   # consume chars until you encounter a "/" or a "."
\K        # "forget" what has been consumed so far
\.        # the dot
Run Code Online (Sandbox Code Playgroud)

因此,匹配用于替换的整个文本仅仅是" .".

取代:

\/      # a slash
Run Code Online (Sandbox Code Playgroud)

结果是一样的.