【问题标题】:Sublime Text 3 Build System: Backslash in a JSONSublime Text 3 构建系统:JSON 中的反斜杠
【发布时间】:2019-09-08 14:50:57
【问题描述】:

我想用MinGW通过Sublime Text编译一个c程序。 我需要运行的命令是:

gcc "${file}" -o "${file_path}\${file_base_name}.exe"

(注意文件路径中的\)

我需要将此字符串写为 JSON 文件中的值。所以,我尝试转换有问题的字符:

" => \"
\ => \\
...

" 字符没有问题,它可以正确转换 - 反斜杠的行为很奇怪。 这是我尝试通过 Sublime 编译时运行的命令:

gcc C:\Users\omer\Desktop${file_base_name}.c -o C:\Users\omer\Desktop${file_base_name}.exe

转换\ => \\不正确?我错过了什么?

编辑:这是完整的构建系统 JSON。

{
"shell_cmd": "gcc \"${file}\" -o \"${file_path}\\${file_base_name}.exe\"",
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"selector": "source.c",

"variants":
[
    {
        "name": "Run",
        "shell_cmd": "gcc \"${file}\" -o \"${file_path}\\${file_base_name}.exe\" && \"${file_path}\\${file_base_name}.exe\""
    }
]

}

【问题讨论】:

  • 您的问题提到知道您需要使用 `\` (这是正确的),但您得到的输出并不反映您这样做了。您能否还包括您的构建系统实际包含的内容?
  • @OdatNurd 在帖子中添加了完整代码。谢谢

标签: json sublimetext3 build-system


【解决方案1】:

对您的问题的简短回答是,您需要在此处进行一些但不是全部转义,因为您需要处理 JSON 转义字符和 Sublime 转义字符,因此您重新被 Sublime 的一个功能所吸引。

我猜你是在 Windows 上,因为你使用 \ 作为路径分隔符; Windows 还允许将/ 用作路径分隔符,因此您可以通过将所有\\ 序列替换为/ 来解决您的问题(总体上看起来也更干净一些)。

下面是解释发生了什么的较长版本的答案(以及解决问题的另一种视觉上更混乱的方法)。


您确实是正确的,在JSON\ 字符是特殊的并引入了转义序列,因此为了在JSON 字符串中有一个文字\ 字符,您需要将其写为@987654330 @ 代替。

不过,Sublime 也支持其自己的 \ 转义序列,因此在某些情况下,您需要在输入文件中使用比预期更多的转义字符才能获得所需的结果。

sublime-build 文件中,Sublime 扩展任何以$ 为前缀的单词作为变量,并用它的值替换整个变量(例如,$file 被替换为当前文件的名称)。这也适用于任何以$ 为前缀的序列,例如$test;在这种情况下,变量的值是空字符串,所以整个变量被替换为空字符串。

此外,Sublime 还在内部将\ 字符处理为“下一个字符不特殊”的意思。因此,如果您需要在构建命令中的某处使用 $ 字符(可能作为命令行参数等),则需要将其引用为 \$ 以告诉 Sublime 不要对其进行特殊处理。

这就是您在上面的输出中看到的;执行的命令包含文本${file_base_name},因为 Sublime 看到字符串的方式告诉它不应该扩展变量。

也许最好用一些例子来说明原因:

"shell_cmd": "echo ${file}"

这将在构建输出中显示当前文件的名称

"shell_cmd": "echo \${file}

在这里,如果您尝试运行构建,没有任何反应,但状态栏会显示No Build System。想法是告诉 Sublime 不要扩展变量,但实际上这是无效的 JSON 因为当处理为 JSON 数据时,\$ 不是有效的转义序列。因此文件加载失败并且没有构建系统可以运行。

"shell_cmd": "echo \\${file}

当它被读取为JSON 时,\\ 被替换为\,而 Sublime 将字符串视为\${file}。当它执行构建时,Sublime 本身将\$ 替换为$,并且构建输出面板中的输出实际上是${file}(即没有扩展)。

最后一个示例显示了在您的情况下发生了什么,\\ 告诉 JSON 加载器这应该是单个 \ 字符,这就是发生的情况。然而,Sublime 随后将 \$ 视为特殊的。

为了扩展文件路径和基本名称以及它们之间的文字 \ 的内容,您需要执行以下操作:

"shell_cmd": "echo ${file_path}\\\\${file_base_name}"

事件的顺序是这样的:

  1. JSON 加载器加载字符串并转换转义序列,因此每个\\ 都被转换为单个\,而Sublime 将字符串视为echo "${file_path}\\${file_base_name}"

  2. 当 Sublime 执行构建时,它会将 \\ 视为单个 \,将完整处理后的字符串保留为 echo "${file_path}\${file_base_name}"

  3. 变量被扩展,你最终得到C:\Users\Me\Desktop\MyFile(或者你有什么),这就是你想要的。

因此,解决您的问题的一种方法是将所有\\ 序列加倍以使它们变为\\\\;然后JSON 处理器将在加载文件时将其转换为您当前拥有的内容,Sublime 将按照您的预期处理它。

总体而言,这很麻烦,但事实证明,在 Windows 上,您可以使用 / 作为路径分隔符,并且它在内部的处理方式与其他任何内容相同,因此更快的解决方案是将 \\ 替换为 / ,它应该为您提供相同的工作解决方案,而不会让人感到困惑。

【讨论】:

  • 哇,非常感谢您的回答!我开始失去希望
猜你喜欢
  • 1970-01-01
  • 2014-10-21
  • 2015-03-01
  • 2013-10-14
  • 1970-01-01
  • 2018-04-27
  • 2015-02-04
  • 1970-01-01
相关资源
最近更新 更多