金|Node.js - 将字符串划分为考虑引号的参数


我正在编写一个不和谐的机器人。Discord是一个带有聊天功能的社交平台,您可以在那里编写机器人代码。


为了触发机器人命令,机器人会读取发送到聊天的每条消息。它以绳子的形式发送给他。


通过使用这个:机器人将每个单词分离成一个数组。现在,我可以这样做:var args = msg.content.split(' ');if (args[0] === '!command') { //code }


我的机器人将跟踪英雄联盟玩家。我希望能够输入名称并添加跟踪原因。所有这些都将进入数据库。起初,这似乎很简单,我可以这样做:


if (args[0] === '!command') {

  var player = args[1];

  var reason = args[2];

}

现在,如果我发送机器人将正确。!command player1 reasons


问题是,在英雄联盟中,允许在昵称中使用空格。同时,原因只有一个词可能不足。如果你试图这样做:机器人不会得到作为args[1],而是,将是args[1],并且将是args[2]。同时,现在将是参数[3]而不是参数[2]。!command "player one" reasonsplayer one"playerone"reasons


有没有一种简单的方法来告诉javascript忽略引号内的空格,这样它就不会在那里拆分字符串?


我可以使用不同的字符来拆分字符串,但是编写这样的命令感觉很奇怪,并且是补丁而不是实际的解决方案。!command-player-reasons there


桃花长相依
浏览 160回答 4
4回答

森林海

更新:因为OP似乎对语言不是很有经验,所以我选择提供一个易于阅读的答案。正确的方法是使用正则表达式捕获组:https://stackoverflow.com/a/18647776/16805283这将检查“message.content”中是否有任何引号,并更改获取 args 数组的方式。如果未找到引号,它将回退到您自己的代码以生成 args 数组。请记住,这只有在“message.content”上正好有2个**引号时才有效,因此不应在原因中使用引号// Fake message object as an exampleconst message = {  content: '!command "Player name with a lot of spaces" reason1 reason2 reason3'};const { content } = message; let args = [];if (content.indexOf('"') >= 0) {  // Command  args.push(content.slice(0, content.indexOf(' ')));  // Playername  args.push(content.slice(content.indexOf('"'), content.lastIndexOf('"') + 1));  // Reasons  args.push(content.slice(content.lastIndexOf('"') + 2, content.length));} else {  args = content.split(' ');}// More code using args如果你想要不带引号的玩家名称:playerName = args[1].replace(/"/g, '');`

守着一只汪

你可以在这里使用正则表达式:const s = `!command "player one" some reason`;function getArgsFromMsg1(s) {&nbsp; const args = []&nbsp; if ((/^!command/).test(s)) {&nbsp; &nbsp; args.push(s.match(/"(.*)"/g)[0].replace(/\"/g, ''))&nbsp; &nbsp; args.push(s.split(`" `).pop())&nbsp; &nbsp; return args&nbsp; } else {&nbsp; &nbsp; return 'not a command'&nbsp; }}// more elegant, but may not workfunction getArgsFromMsg2(s) {&nbsp; const args = []&nbsp; if ((/^!command/).test(s)) {&nbsp; &nbsp; args.push(...s.match(/(?<=")(.*)(?=")/g))&nbsp; &nbsp; args.push(s.split(`" `).pop())&nbsp; &nbsp; return args&nbsp; } else {&nbsp; &nbsp; return 'not a command'&nbsp; }}console.log(getArgsFromMsg1(s));console.log(getArgsFromMsg2(s));

月关宝盒

我建议你单独解析命令和它的参数。它将承认编写更灵活的命令。例如:var command = msg.content.substring(0, msg.content.indexOf(' '));var command_args_str = msg.content.substring(msg.content.indexOf(' ') + 1);switch(command) {&nbsp; &nbsp; case '!command':&nbsp; &nbsp; &nbsp; &nbsp; var player = command_args_str.substring(0, command_args_str.lastIndexOf(' '));&nbsp; &nbsp; &nbsp; &nbsp; var reason = command_args_str.substring(command_args_str.lastIndexOf(' ') + 1);&nbsp; &nbsp; &nbsp; &nbsp; break;}

潇潇雨雨

这是可能的,但对于机器人的用户来说,只使用不同的字符来拆分两个参数可能不那么复杂。例如 如果您知道(或 ,等)不是有效用户名的一部分。!command player one, reasons,|=>如果您只支持用户名部分的引号,则更容易:const command = `!command`;const msg1 = {content: `${command} "player one" reasons ggg`};const msg2 = {content: `${command} player reasons asdf asdf`};function parse({content}) {&nbsp; if (!content.startsWith(command)) {&nbsp; &nbsp; return; // Something else&nbsp; }&nbsp; content = content.replace(command, '').trim();&nbsp; const quotedStuff = content.match(/"(.*?)"/);&nbsp; if (quotedStuff) {&nbsp; &nbsp; return {player: quotedStuff[1], reason: content.split(`"`).reverse()[0].trim()};&nbsp; } else {&nbsp; &nbsp; const parts = content.split(' ');&nbsp; &nbsp; return {player: parts[0], reason: parts.slice(1).join(' ')};&nbsp; }&nbsp; console.log(args);}[msg1, msg2].forEach(m => console.log(parse(m)));
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript