首页 > 解决方案 > 将引号内的内容计算为一个参数

问题描述

我正在使用 node.js 的 discord.js 模块制作一个不和谐机器人,我有一个基本的参数检测系统,它使用空格作为分隔符并将不同的参数放在一个数组中,这是我的代码的重要部分。(我正在使用单独的命令模块module.exports)。

const args = message.content.slice(prefix.length).split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName) || client.commands.find(cmd => cmd.alias && cmd.alias.includes(commandName));

例如,当有人写!give foo 50 bar. args 数组是['foo','50','bar']
我希望args不要在命令中划分命令的引用部分,这意味着如果 somenoe 写入!give "foo1 bar1" 50 "foo2 bar2". 我希望args返回这样的数组['foo1 bar1', '50','foo2 bar2']而不是['foo1','bar1','50','foo2','bar1',]

标签: javascriptarraysnode.jsargumentsdiscord.js

解决方案


这可能不是最有效的方法,但我认为它是可以理解的:我们可以扫描每个字符并跟踪我们是在几个引号之内还是之外,如果是,我们忽略空格。

function parseQuotes(str = '') {
  let current = '',
    arr = [],
    inQuotes = false
    
  for (let char of str.trim()) {
    if (char == '"') {
      // Switch the value of inQuotes
      inQuotes = !inQuotes
    } else if (char == ' ' && !inQuotes) {
      // If there's a space and where're not between quotes, push a new word
      arr.push(current)
      current = ''
    } else {
      // Add the character to the current word
      current += char
    }
  }
      
  // Push the last word
  arr.push(current)
    
  return arr
}

// EXAMPLES
// Run the snippet to see the results in the console

// !give "foo1 bar1" 50 "foo2 bar2"
let args1 = parseQuotes('!give "foo1 bar1" 50 "foo2 bar2"')
console.log(`Test 1: !give "foo1 bar1" 50 "foo2 bar2"\n-> [ "${args1.join('", "')}" ]`)

// !cmd foo bar baz
let args2 = parseQuotes('!cmd foo bar baz')
console.log(`Test 2: !cmd foo bar baz\n-> [ "${args2.join('", "')}" ]`)

// !cmd foo1 weir"d quot"es "not closed
let args3 = parseQuotes('!cmd foo1 weir"d quot"es "not closed')
console.log(`Test 3: !cmd foo1 weir"d quot"es "not closed\n-> [ "${args3.join('", "')}" ]`)


推荐阅读