如何根据字数分割文本

时间:2018-11-09 11:56:06

标签: node.js split discord.js

我正在尝试使用discord.jscheerio和名为genius.com的网站来制作歌词项目。
我成功地找到了一种从网站上抓取歌词的方法,我需要将其拆分,因为discord的最大字数限制为2000。
我可以通过执行lyrics.length来检查整个歌词中有多少个字符/单词,我只需要找到一种方法来分割字符串并发送两者,将来我可能会实现richEmbeds更时尚,但现在我只关注基础知识。

var request = require('request');
var cheerio = require('cheerio');

/*
This is a project for my discord bot, the reason for the 2000 word limit is because 
discords character limit is currently set to 2000, this means that i will have to add
a function to split the lyrics and send each part
*/

//Define the URL that we are going to be scraping the data from
var UR_L = "https://genius.com/Josh-a-and-jake-hill-not-afraid-of-dying-lyrics";

//send a request to the website and return the contents of the website
request(UR_L, function(err, resp, body) {
  //load the website using cheerio
  $ = cheerio.load(body);

  //define lyrics as the selector to text form
  var lyrics = $('p').text();

  if (lyrics.length > "2000" && lyrics.length < "4000") {

  } else if (lyrics.length > "4000" && lyrics.length < "6000") {

  } else {
    //send the lyrics as one message
  }
})

您可以在repl.it上找到运行here的实时版本。

3 个答案:

答案 0 :(得分:1)

您不需要使用任何高级功能,该功能已经内置在discord.js中:您可以在消息中附加一些选项,而MessageOptions.split是您要搜索的内容。当您要发送文本时,请按照以下步骤操作:

channel.send(lyrics, { split: true });

如果lyrics.length大于限制,discord.js将会剪切您的消息并依次发送,使其看起来像是一条消息。
channel是您要将消息发送到的TextChannel

答案 1 :(得分:0)

您可以使用.split( ) Javascript函数。

word_list = lyrics.split(" ")

然后用word_list.length访问消息中的单词数,然后用word_list[0]选择第一个单词。

答案 2 :(得分:0)

Discord has a 2000 characters limit不能超过2000个字。

解决您问题的一种方法可能是:

// This will result in an array with strings of max 2000 length
const lyricsArr = lyrics.match(/.{1,2000}/g);  

lyricsArr.forEach(chunk => sendMessage(chunk))

鉴于发送消息的异步性质,您可能希望研究p-iteration之类的模块,以确保块以正确的顺序到达。

话虽这么说,但现在有一些API可以获取歌曲的歌词,我建议您使用它而不是抓取。参见apiseeds歌词API。

更新

    const lyrics = 'These are my lyrics';

    const lyricsArr = lyrics.match(/.{1,8}/g); 

    console.log(lyricsArr); // [ 'These ar', 'e my lyr', 'ics' ]

    lyricsArr.forEach((chunk, i) => {
      // Break if this is the last chunk.
      if (i == lyricsArr.length -1) {
        return;
      }
      // If last character is not a space, we split a word in two.
      // Add additional non-wordbreaking symbols between the slashes (in the regex) if needed.
      if (!chunk[chunk.length - 1].match(/[ ,.!]/)) {
        const lastWord = chunk.match(/\s([^ .]+)$/)
        lyricsArr[i + 1] = lastWord[1] + lyricsArr[i + 1];
        lyricsArr[i] = lyricsArr[i].split(/\s[^ .]*$/)[0];
      }
    })

    console.log(lyricsArr) // [ 'These', 'are my', 'lyrics' ]

已根据评论进行了更新。 这是一些我不花很多时间的粗略代码,但确实可以完成工作。

使用此方法时的一些信息:

  • 您需要在第二个if中向正则表达式添加不应该被认为是断字的任何符号
  • 此功能尚未经过彻底测试,因此使用后果自负。
  • 如果歌词中的单词长于块大小,则肯定会中断。由于大约是2000年,我想这不会有问题。
  • 这将不再确保数据块长度低于限制,因此将限制更改为1900左右是安全的