VSCode高级代码段转换

时间:2019-06-21 21:09:51

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

我正在尝试创建一个片段,该片段基于文件路径创建一个类名。如果文件名为index.js,我希望类名采用文件夹名。否则,请使用文件名。

如果文件名为index.js(正确插入文件夹名称),则我正在执行一种转换(如下所示)。

我将如何扩展(假设甚至有可能)第二种情况?

我确实从VSCode documentation中注意到,可以使用一些基本的if / else格式,这些格式仅在存在捕获组的情况下才插入给定的文本。我已经能够通过一些简单的例子来帮助那些人。但不确定是否可以以某种方式使用它们来完成我想做的事情。

当前代码段:

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

3 个答案:

答案 0 :(得分:2)

@Wiktor稍后会添加正确的答案,但我想对vscode的变量转换中的那些条件发表一些评论。

如果您可以做这样的事情,那将是非常好的:

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

有条件的如果组3不为空,则插入组1(父目录),否则,插入组2(文件名)。但这虽然正则表达式没问题(尽管简化了re:路径分隔符和文件扩展名),但这并不起作用。

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

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

不支持,似乎在条件文本替换中使用正则表达式组。从语法链接来看,这似乎是遵循的(请参见代码段语法1。查看有关条件的这一部分:

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

我要说的是,不支持在条件性if / else部分中捕获的组。它似乎并未明确允许捕获组-仅当/否则为纯文本时。

答案 1 :(得分:1)

借助Wiktor对regex的熟练掌握,再加上文档,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}/};"
    ]
  }
}

答案 2 :(得分:1)

我建议使用

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

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

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

正则表达式1可以在as shown hereregex #2 here下运行,请参见its graph

enter image description here

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

正则表达式详细信息

请注意,由于模式是作为字符串文字形式传递的,因此反斜杠加倍,因为字符串文字包含“字符串化”的正则表达式文字,因此必须转义/字符。

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

因此,完整的代码段看起来像

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

随时根据需要进行调整。