【问题标题】:Regex for SublimeText SnippetSublimeText 片段的正则表达式
【发布时间】:2013-09-09 21:15:55
【问题描述】:

我现在在这个 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

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

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

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

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

:]

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

【问题讨论】:

  • [...] 是否真的在你的字符串中,或​​者你是说你的字符串中有不同数量的实际文件夹?
  • 你能保证文件总是有一个文件扩展名(因此包含一个句点)吗?在这种情况下,我可以想出一个丑陋但有效的单正则表达式解决方案。否则,这将是艰难的。
  • 我可以假设该文件将始终使用扩展名,因为我只会将 sn-p 用于 AS3 类。

标签: regex sublimetext2 sublimetext


【解决方案1】:

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

首先,我们要删除直到最后一个 src/ 的所有内容(为了模仿您的 sn-p 的行为 - 如果您想删除直到第一个 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 正则表达式引擎的在线测试仪。但这应该可以解决问题。

【讨论】:

  • 感谢您的详细解答。但是,我仍然很不明白如何处理这些信息。尝试时: ${TM_FILEPATH/.+/src/|\G([^/]+)/(?=[^/]+/.*([.]))|\G([^/]+) /[^/]+$} 我只收到'src'。但是在使用您的 Demo 测试时,我可以看到 Regex 表达式应该显示正确的值。
  • @caubry 在我的回答中我发布了所有没有分隔符的模式。似乎在您的环境中您确实需要定界符(斜杠),因此模式中的所有斜杠都需要转义。您还需要添加替换字符串:${TM_FILEPATH/.+\/src\/|\G([^\/]+)\/(?=[^\/]+\/.*([.]))|\G([^\/]+)\/[^\/]+$/$1$2$3}
  • 输入给定值时,不会显示此 sn-p 的输出。在正则表达式末尾添加分隔符时,我得到: $‌​2com/[...]/folder/MyClass.as 再次感谢,我尝试了不同的差异,但我仍然无法显示期望的输出.这太令人困惑了:s 我更好地理解这句话“众所周知,正则表达式会伤害人们的感情。” - bit.ly/HXC8WU -_-
  • @caubry 哦,是的,看来您需要为模式...$1$2$3/g/} 添加另一个分隔符和全局修饰符。抱歉,我无法为您进行 sublime 测试。 :-/
  • 非常感谢您的耐心等待 :D 它运行良好!答案是:${TM_FILEPATH/.+\/src\/|\G([^\/]+)\/(?=[^\/]+\/.*([.]))|\G ([^\/]+)\/[^\/]+$/$1$2$3/g/}
猜你喜欢
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
相关资源
最近更新 更多