4

我现在已经在这个 Sublime Snippet 上停留了一段时间。

我想在创建新类时显示正确的包名称,使用TM_FILEPATHand TM_FILENAME

打印TM_FILEPATH变量时,我得到如下信息:

/Users/caubry/d/[...]/src/com/[...]/folder/MyClass.as

我想转换这个输出,所以我可以得到类似的东西:

com.[...].folder

这包括:

  • 删除之前的任何东西/com/[...]/folder/MyClass.as
  • 删除 TM_FILENAME 及其扩展名;在这个例子中MyClass.as
  • 最后找到所有的斜线并用点替换它们。

到目前为止,这就是我所拥有的:

${1:${TM_FILEPATH/.+(?:src\/)(.+)\.\w+/\l$1/}}

这显示:

com/[...]/folder/MyClass

我确实了解如何用点替换飞溅,例如:

${1:${TM_FILEPATH/\//./g/}}

但是,我很难将此逻辑添加到前一个逻辑,以及删除逻辑末尾的 TM_FILENAME 。

我对正则表达式真的很缺乏经验,在此先感谢。

:]

编辑: [...]表示可变数量的文件夹。

4

1 回答 1

4

我们可以通过一些技巧在一次替换中做到这一点。我们要做的是,我们将几个不同的案例放入我们的模式中,并对它们中的每一个进行不同的替换。实现这一点的诀窍是替换字符串不能包含文字字符,而是完全由“反向引用”组成。在这种情况下,那些没有参加比赛的组(因为他们是不同案例的一部分)将被简单地写回一个空字符串,并且不参与替换。让我们开始吧。

首先,我们要删除直到最后的所有内容src/(以模仿您的片段的行为 - 如果您想删除直到第一个的所有内容,请使用不贪婪的量词src/):

^.+/src/

我们只是想放弃它,所以不需要捕获任何东西——也不需要写回任何东西。

现在我们要匹配后续文件夹,直到最后一个。我们将捕获文件夹名称,也匹配尾随的/,但写回文件夹名称和.. 但是我说替换字符串中没有文字!所以.也必须来自捕获​​。这里有一个假设,即您的文件始终具有扩展名。我们可以通过前瞻从文件名中获取句点。我们还将使用该前瞻来确保前面至少还有一个文件夹:

^.+/src/|\G([^/]+)/(?=[^/]+/.*([.]))

我们将用$1$2. 现在,如果第一个替代项捕获,则分组$1并将$2为空,并且仍然删除前导位。如果第二个选项捕获,$1将是文件夹名称,并且$2将捕获一个句点。甜的。The\G是一个锚点,可确保所有匹配项彼此相邻。

最后,我们将匹配最后一个文件夹及其后面的所有内容,并且只写回文件夹名称:

^.+/src/|\G([^/]+)/(?=[^/]+/.*([.]))|\G([^/]+)/[^/]+$

现在我们将把它替换$1$2$3为最终的解决方案。演示。

概念上相似的变体是:

^.+/src/|\G([^/]+)/(?:(?=[^/]+/.*([.]))|[^/]+$)

替换为$1$2. 我真的只考虑了第二个和第三个选择的开始。演示。

最后,如果 Sublime 使用Boost 的扩展格式字符串语法,实际上可以有条件地将字符放入替换中(无需神奇地从文件扩展名中变出它们):

^.+/src/|\G(/)?([^/]+)|\G/[^/]+$

现在我们有第一个替代方案src(将被删除),最后一个斜杠和文件名(将被删除)的第三个替代方案,以及您要保留的所有文件夹的中间替代方案。这次我把要替换的斜线可选地放在开头。通过条件替换.,当且仅当该斜线匹配时,我们可以在那里写:

(?1.:)$2

不幸的是,我现在无法对此进行测试,而且我不知道使用 Boost 正则表达式引擎的在线测试仪。但这应该可以解决问题。

于 2013-09-09T21:43:28.333 回答