我们可以通过一些技巧在一次替换中做到这一点。我们要做的是,将一些不同的情况放入我们的模式中,并对每个情况进行不同的替换。实现此目的的技巧是替换字符串不得包含文字字符,而完全由“反向引用”组成。在这种情况下,那些没有参加比赛的组(因为它们是不同案例的一部分)将简单地作为空字符串写回,而不会参与替换。让我们开始吧。
首先,我们要删除直到最后的所有内容src/
(模仿您的代码片段的行为 - 如果您想删除第一个之前的所有内容,请使用不贪婪的量词src/
):
^.+/src/
我们只是想删除它,所以不需要捕获任何东西 - 也不需要写回任何东西。
现在我们要匹配后续文件夹直到最后一个。我们将捕获文件夹名称,并匹配尾随/
,但写回文件夹名称和.
。但我说替换字符串中没有文字!所以.
也必须来自捕获。这里的假设是,你的文件总是有一个扩展名。我们可以通过前瞻从文件名中获取句点。我们还将使用该前瞻来确保前面至少还有一个文件夹:
^.+/src/|\G([^/]+)/(?=[^/]+/.*([.]))
我们将其替换为$1$2
。现在,如果第一种选择成功,则分组$1
and $2
将为空,并且前导位仍然被删除。如果第二种选择成功,$1
将是文件夹名称,并且$2
将捕获一个时期。甜的。这\G
是一个锚点,确保所有匹配项彼此相邻。
最后,我们将匹配最后一个文件夹及其后面的所有内容,并且只写回文件夹名称:
^.+/src/|\G([^/]+)/(?=[^/]+/.*([.]))|\G([^/]+)/[^/]+$
现在我们将其替换为$1$2$3
以获得最终解决方案。Demo. http://regex101.com/r/bC9nS5
概念上类似的变体是:
^.+/src/|\G([^/]+)/(?:(?=[^/]+/.*([.]))|[^/]+$)
替换为$1$2
。我实际上只考虑了第二个和第三个选择的开头。Demo. http://regex101.com/r/kP9tG3
最后,如果 Sublime 使用的是Boost 的扩展格式字符串语法 http://www.boost.org/doc/libs/1_53_0/libs/regex/doc/html/boost_regex/format/boost_format_syntax.html,实际上可以有条件地将字符放入替换中(无需从文件扩展名中神奇地召唤它们):
^.+/src/|\G(/)?([^/]+)|\G/[^/]+$
现在我们有了第一个选择src
(将被删除),最后一个斜杠和文件名的第三个选择(将被删除),以及要保留的所有文件夹的中间选择。这次我把要替换的斜杠放在开头。通过条件替换,我们可以写一个.
当且仅当该斜杠匹配时:
(?1.:)$2
不幸的是,我现在无法对此进行测试,而且我不知道使用 Boost 正则表达式引擎的在线测试器。但这应该可以很好地解决问题。