VS代码嗅探器转换:if(regex matches X){ use transform A } else if(regex matches Y){ use transform B }

yhxst69z  于 2023-10-22  发布在  其他
关注(0)|答案(3)|浏览(82)

我正在尝试创建一个基于文件路径创建类名的代码段。如果文件名为index.js,我希望类名采用文件夹名。否则,使用文件名。
我有一个转换(如下所示),如果文件名为index.js(它正确地插入了文件夹名称),它目前正在工作。
我如何在此基础上进行扩展(假设这是可能的),使其也适用于第二种情况?
我从VSCode文档中注意到,您可以使用一些基本的if/else格式,这些格式仅在捕获组存在时才插入给定的文本。我已经能够让这些工作与一些简单的例子。但不确定这些是否能以某种方式用来完成我想做的事情。
当前片段:

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

oxcyiej71#

我建议使用

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

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

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

正则表达式#1将工作as shown hereregex #2 here,请参见其图形:

这里的要点是使用两个替换项,用|交替操作符分隔,在 * 捕获 * 您需要的部分时匹配 * 整个 * 字符串,确保更具体的(具有已知文件名)替换项放在第一位,更通用的(将匹配 * 任何 * 文件名)将放在最后。替换模式将是两个反向引用$1$2,因为在找到匹配后,只有一个实际上包含一些文本。

Regex详细信息

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

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

因此,完整的代码片段如下所示:

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

你想怎么调整都行。

mo49yndu

mo49yndu2#

@Wiktor稍后会添加正确的答案,但我想说的是vscode的变量转换中的那些条件太长了,无法注解。
如果你能做这样的事情,那就太好了:
"${TM_FILEPATH/.*\\(.+)\\((index\\.js)|(.*))/${3:?$1:$2}}/g}",
条件ifgroup 3 isn 't empty插入group 1(父目录)else插入group 2(文件名).但是这并不起作用,尽管正则表达式很好(尽管简化了re:路径分隔符和文件扩展名)。
不幸的是,虽然一个“普通”条件确实工作得很好:

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

在条件文本替换中使用正则表达式组似乎不支持。这似乎是从语法链接中得出的(参见snippet grammar)1。看看这部分关于条件句的内容:

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

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

j13ufse2

j13ufse23#

有了Wiktor在评论中对正则表达式的掌握,结合文档,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}/};"
    ]
  }
}

相关问题