SublimeText Snippet的正则表达式

时间:2013-09-09 21:15:55

标签: regex sublimetext2 sublimetext

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

我想在使用TM_FILEPATHTM_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

我知道如何用点替换splashes,例如:

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

但是,我很难将此逻辑添加到上一个逻辑,以及在逻辑结束时删除TM_FILENAME。

我对Regex缺乏经验,提前谢谢。

:]

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

1 个答案:

答案 0 :(得分:4)

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

首先,我们要删除所有内容,直到上一个src/(模仿你的代码段的行为 - 如果要删除所有内容,请使用不合格的量词,直到第一个src/):

^.+/src/

我们只想放弃它,所以不需要捕捉任何东西 - 也不需要写任何东西。

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

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

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

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

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

现在我们将用$1$2$3替换为最终解决方案。 Demo.

概念上类似的变体将是:

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

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

最后,如果Sublime正在使用Boost's extended format string syntax,实际上可以有条件地将字符放入替换中(不会从文件扩展名中巧妙地将它们变为魔术):

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

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

(?1.:)$2

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