For my needs I write a telegram-bot. Api has a limit on the size of a single message - 4096 characters.

This is how I get the variable with the file search results:

with open('filename.list', 'r') as f: for line in f.readlines(): if searchstring.lower() in line.lower(): result= str(result) + str(line) + '\n' 

Example result:

String1 param1 param2 \ n String2 param1 param2 \ n

etc.

Further, this result is sent by the message:

 if result: bot.send_message(chat_id="SomeID", text= str(result) ) 

How can I divide a message with the result into several messages, in case of exceeding the limit? At the same time, by doing this line by line, so that the results of a half-line are not transferred to me.

  • one
    in the forehead it is done like this - eval.in/934891 - splash58
  • aside: do not use .readlines() here. The file in Python is already a row iterator. Do not use str() on strings (and avoid explicitly calling at all) - this is useless. If not difficult, can you mention where you saw the for line in f.readlines() construction (instead of for line in file )? What do you want to achieve by calling str() ? - jfs

3 answers 3

So it is possible:

 s = 'string1\nstring2\nstring3\n' * 10000 while s: if len(s) > 4096: tmp = s[:s.rfind('\n',0,4096)+1] s = s[s.rfind('\n',0,4096)+1:] bot.send_message(chat_id="SomeID", text=tmp ) else: bot.send_message(chat_id="SomeID", text=s ) break 
  • if the length of one line is more than 4096, the code will not work. s.rfind + 1 there’s no need to double out - vadim vaduxa

To send selected lines from a file in chunks, without exceeding the limit on the number of characters [approximately]:

 with open(filename) as file: chunk = file.readlines(limit) while chunk: found_lines = [line for line in chunk if searchstring in line.casefold()] if found_lines: send(''.join(found_lines)) chunk = file.readlines(limit) 

You can count the size of your hands so that you can determine your conditions for the limit, for example, in bytes in the selected encoding read:

 chunksize = 0 chunk = [] with open(filename) as file: for line in file: if searchstring in line.casefold(): chunksize += len(line.encode()) if chunksize > limit: # send chunk send(''.join(chunk)) del chunk[:] chunksize = len(line.encode()) chunk.append(line) if chunk: # send the rest send(''.join(chunk)) 

    shorter answer Iriskin

     s = 'string1\nstring2\nstring3\n' * 10 def maxll(s, lmax=90): if s: m = s.rfind('\n', 0, lmax) + 1 tmp = s[:m] print(len(tmp), tmp) # bot.send_message(chat_id="SomeID", text=tmp) return maxll(s[m:]) 

    if the length of one line is greater than lmax, it will not work