VS 代码片段变换: if (正则表达式匹配 X) { 使用变换 A } else if (正则表达式匹配 Y) { 使用变换 B }

问题描述 投票:0回答:3

我正在尝试创建一个片段,该片段根据文件路径创建类名。如果文件名为

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};"
    ]
  },
}
javascript regex visual-studio-code code-snippets vscode-snippets
3个回答
6
投票

我建议使用

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

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

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

正则表达式#1将工作如此处所示正则表达式#2此处,请参阅其图表

这里的重点是使用两个用

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

正则表达式详细信息

请注意,反斜杠是双倍的,因为模式作为字符串文字传递,并且

/
字符必须转义,因为字符串文字包含“字符串化”正则表达式文字。

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

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

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

您可以随意调整。


3
投票

@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}

似乎不支持在条件文本替换中使用正则表达式组。这似乎是从语法链接得出的(请参阅语法片段]1。查看有关条件的这部分:

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

我想说的是,不支持条件 if/else 部分中捕获的组。它似乎没有明确允许捕获组 - 仅当/否则纯文本。


2
投票
凭借 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}/};" ] } }
    
© www.soinside.com 2019 - 2024. All rights reserved.