【问题标题】:VSCode Advanced Snippet TransformVSCode 高级代码段转换
【发布时间】:2019-11-04 17:19:08
【问题描述】:

我正在尝试创建一个基于文件路径创建类名的 sn-p。如果文件名为index.js,我希望类名取文件夹名。否则,使用文件名。

如果文件名为index.js(它正确插入文件夹名称),我有一个当前正在工作的转换(如下所示)。

我将如何扩展这一点(假设它甚至可能)也适用于第二种情况?

我确实从VSCode documentation 中注意到,您可以使用一些基本的 if/else 格式,如果存在捕获组,它们只会插入给定的文本。我已经能够让那些使用一些简单的例子。但不确定这些是否可以以某种方式用于完成我正在尝试做的事情。

当前sn-p:

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
        "class ${TM_FILEPATH/[\\/\\w$]+\\/(?!index)|\\/index.js//g} {}",
        "export default ${TM_FILEPATH/[\\/\\w$]+\\/(?!index)|\\/index.js//g};"
    ]
  },
}

【问题讨论】:

  • 那么,如果index.jsc:\Users\wiktor\Documents\index.js 中,那么类应该是Documents?如果是C:\index.js呢?
  • @WiktorStribiżew 对,我已经让这部分与上述内容一起工作。不过,我还没有第二种情况工作(如果文件名不是索引,请在文件后命名)。在您询问的情况下,不会使用此 sn-p 。我并不是真的试图防范所有边缘情况。这将是一个特定于工作流的 sn-p。
  • 试试${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*)/$1$2/}。注意我添加了/\ 路径分隔符。
  • regex101.com/r/8xFzXL/1,这就是它的工作原理。是否按预期工作?
  • @WiktorStribiżew 正则表达式解决方案非常完美,谢谢!必须进行一些调整,因为正如 Mark 所提到的,使用 VSCode 转换引用正则表达式组是有限的。随意在我的答案中复制/粘贴我的代码示例并将其作为新答案发布,我会给你信用。再次感谢!

标签: javascript regex visual-studio-code code-snippets vscode-snippets


【解决方案1】:

我建议使用

${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*)/$1$2/}

如果您不想在输出中包含文件扩展名,请使用

${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*?)(?:\\.[^.]*)$/$1$2/}

正则表达式 #1 可以使用 as shown hereregex #2 here,请参阅 its graph

这里的重点是使用两个用 | 交替运算符分隔的替代方案,它们将匹配 整个 字符串,同时 捕获 您需要的部分,确保更具体(具有已知文件名)替代方案首先出现,更通用的替代方案(将匹配 any 文件名,将在最后。替换模式将是两个反向引用,$1$2,因为只有一个在找到匹配项后实际上会包含一些文本。

正则表达式详细信息

注意反斜杠是双倍的,因为模式是作为字符串文字传递的,并且/ 字符必须转义,因为字符串文字包含“字符串化”的正则表达式文字。

  • .*[\/\\]([^\/\\]+)[\/\\]index\.js$:
    • .* - 除换行符以外的任何 0+ 个字符,尽可能多
    • [\/\\] - /\
    • ([^\/\\]+) - 捕获组 1:除 /\ 之外的一个或多个 (+) 字符([^...] 是一个否定字符类)
    • [\/\\] - /\
    • index\.js - index.js 子字符串
    • $ - 字符串结束
  • | - 或
  • .*[\/\\](.*):
    • .* - 除换行符以外的任何 0+ 个字符,尽可能多
    • [\/\\] - /\
    • (.*) - 捕获组 2:除换行符之外的任何 0+ 个字符,尽可能多
    • (.*?)(?:\.[^.]*)?$ - 将尽可能少地捕获除换行符之外的任何 0 个或多个字符到第 2 组,然后将尝试匹配可选序列 . 和 0+ 个非点字符,直到末尾字符串 ($)。

所以,完整的代码 sn-p 看起来像

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
      "class ${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*?)(?:\\.[^.]*)$/$1$2/} {}",
      "export default ${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*?)(?:\\.[^.]*)$/$1$2/};"
    ]
  }
}

随意调整。

【讨论】:

    【解决方案2】:

    @Wiktor 稍后会添加正确答案,但我想谈谈 vscode 变量转换中的那些条件,因为这些条件太长,无法评论。

    如果你能做这样的事情那就太好了:

    "${TM_FILEPATH/.*\\(.+)\\((index\\.js)|(.*))/${3:?$1:$2}}/g}",

    条件 if 组 3 不为空插入组 1(父目录)else 插入组 2(文件名)。但这不起作用,尽管正则表达式很好(尽管简化了 re: 路径分隔符和文件扩展名)。

    不幸的是,虽然“普通”条件确实可以很好地工作:

    ${3:?There is an index.js file:There is not an index.js file}
    

    似乎不支持在条件文本替换中使用正则表达式组。这似乎来自语法链接(参见 sn-p 语法]1。看看这部分关于条件的内容:

    '${' int ':?' if ':' else '}' 
    

    我会说不支持条件 if/else 部分中的捕获组。它似乎并没有明确地允许捕获组 - 只有 if/else 纯文本。

    【讨论】:

      【解决方案3】:

      凭借 Wiktor 在 cmets 中对正则表达式的掌握,结合文档、Mark 的进一步见解以及一些额外的调整(由于 VSCode 转换限制,正则表达式捕获组被替换/转换的方式),我终于能够制定一个可行的解决方案。

      {
        "mySnippet": {
          "prefix": "cls",
          "body": [
            "class ${TM_FILEPATH/(.*[\\/\\\\])([^\\/\\\\]+)([\\/\\\\]index\\.[jt]s$)|(.*[\\/\\\\])(.*)(\\.[jt]s)/${2}${5}/} {}",
            "export default ${TM_FILEPATH/(.*[\\/\\\\])([^\\/\\\\]+)([\\/\\\\]index\\.[jt]s$)|(.*[\\/\\\\])(.*)(\\.[jt]s)/${2}${5}/};"
          ]
        }
      }
      

      【讨论】:

      • 我更新了正则表达式,只返回不带扩展名的文件名。
      猜你喜欢
      • 2020-10-14
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多