【问题标题】:Why does it add backslashes in the saved file?为什么它在保存的文件中添加反斜杠?
【发布时间】:2021-01-03 14:53:56
【问题描述】:

我有一些代码应该已经在 .json 文件中保存一个单词和其他单词,它 KINDA 完成了这项工作,它将文件(fs.readFileSync)读取为 const 并在使用 fs.WriteFileSync 保存时它只是像这样

我不知道它为什么会这样做,但它真的很烦人(readBl 是一个读取它并将它保存为变量的函数,所以当我想用命令读取它时,我知道我除了 IDC 之外,可以通过其他方式做到这一点)我的代码:

if(msg.content.startsWith('-addconf '))
  {
    var newword = msg.content.slice(9);

    if(blacklisted.includes(newword))
      return msg.channel.sendMessage("This word has already been blacklisted.")

    let rawdata = fs.readFileSync('blacklist.json');
    let rawRead = JSON.parse(rawdata);

    const str = JSON.stringify(rawRead);

    const str1 = str.replace('}', '');
    const str2 = str1.replace('{"blacklist":', '');
    //const str3 = str2.replace('""', '');

    let balance = {
    blacklist: str2 + newword
    };

    let data = JSON.stringify(balance);
    fs.writeFileSync('blacklist.json', data);

    readBl();
    msg.channel.sendMessage("Added a blacklisted word, test it out.")
}

【问题讨论】:

  • 读取文件功能:pastebin.com/GeE4ja2a
  • 因为您要转换为 JSON 的字符串值已经包含双引号。这些需要转义才能成为有效的 JSON。简单示例:console.log(JSON.stringify('string with "double quotes"'))。您正在对 JSON 数据进行字符串替换这一事实意味着您采用了错误的方法。你到底想达到什么目的?输入和预期输出是什么?
  • 反斜杠是转义字符。 JSON 必须转义引号和反斜杠。如果你使用 JSON.parse 转义字符应该消失。
  • 同样,反斜杠是转义字符。想象一下,如果您在一组引号中放置多个引号。引号会相互抵消,导致奇怪的行为。反斜杠通知这些引号在您所做的引号内。这告诉计算机这些引号是您拥有的字符串的一部分,而不仅仅是另一个引号。
  • 我想创建一个黑名单,所以如果你输入“-addconf ”它会将该单词保存到一个文件中,当机器人启动时(或者你添加一个新单词)它会保存黑名单作为一个 var,所以我可以稍后检查消息的内容中是否确实包含一些列入黑名单的单词。我怎样才能做到这一点? @Felix Kling

标签: javascript json discord discord.js fs


【解决方案1】:

JSON 值(如键)用双引号括起来。

{ "someKey": "someValue" } 

那么,如何编写一个包含引号的值,例如some"Value"With"Quotes"In"It?而且你在这里可能会更糟......

(更重要的是,JSON 解析器应该如何读回这样的值?

值是some?这是语法错误吗?

在 JSON 中,就像在许多其他需要分隔符的上下文中一样,我们需要有一种方法来告诉引号 " 不是结束值的语法元素,而是作为一部分的某些字符价值。

解决办法:转义

所以我们做了所谓的“转义”角色。在 JSON(和其他语言)中,转义是通过以反斜杠 \ 为前缀来完成的。

而且...既然反斜杠现在也是一个特殊字符,用于转义另一个字符,那么您又遇到了同样的问题:如何在值本身中表示实际的反斜杠?

简单,相同的解决方案:您将反斜杠本身转义。

所以,当保存一个 JSON 字符串值时:

  • 引用"变成\"
  • 反斜杠\变成\\

如何读回来?

任何功能正常的 JSON 阅读器都能正确读取,这是序列化这些字符的正确方法,因此您在这里没有任何问题!

【讨论】:

    【解决方案2】:

    我想创建一个阻止列表,因此如果您键入“-addconf”,它将将该单词保存到一个文件中,并且当机器人启动(或您添加一个新单词)时,它将黑名单保存为 var,以便我稍后检查如果消息的内容实际上包含一些列入黑名单的单词。我怎样才能做到这一点?

    您可以通过将单词存储在数组中来实现这一点。您只需要在代码启动时读取一次文件,然后将其添加到数组并将其写入文件即可。

    // At the beginning
    // blacklist.json needs to contain {"blacklist": []}
    let {blacklist} = JSON.parse(fs.readFileSync('blacklist.json'));
    
    // Wherever...
    if(msg.content.startsWith('-addconf '))
      {
        var newword = msg.content.slice(9);
    
        if(blacklist.includes(newword)) {
          return msg.channel.sendMessage("This word has already been blacklisted.")
        }
    
        blacklist.push(newword);
        fs.writeFileSync('blacklist.json', JSON.stringify({blacklist}));
    
        msg.channel.sendMessage("Added a blacklisted word, test it out.")
    }
    

    您甚至可以直接将数组存储在文件中,无需使用具有blacklist 属性的对象(除非您想存储其他数据。


    你最终得到这么多反斜杠的原因是你的字符串操作可能不太有效,所以你最终得到了乱码。如果您正确地构建数据,则不需要这样做。

    【讨论】:

      猜你喜欢
      • 2012-05-06
      • 2019-02-22
      • 2021-07-30
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      相关资源
      最近更新 更多