Hey,
The while statement isn't just so slow to me but for anyone.
The mIRC scripting language isn't really fast, a while statement is slow and should be avoided when possible.
The code you suggested had two nested while loop, which is going to be slow, but moreover, you're using $read in a way that avoids searching the whole file, rather you read line by line, which means that each time $read is called, mirc will open the file (/fopen), parse it to get the Nth line as mentioned (calling /fseek -n, N times), close the file (/fclose) and return the result, all of these operation are accessing the file system, it's super-slow.
Also, you're using $lines() as part of the condition in the while loop instead of putting that value in a %variable, $lines() involve the same operations as $read, you're to evaluate it each time, but it won't change in value.
Of course, if you have like 5-6 tokens in $1- and 5-6 lines in the file, even the slowest code would perform rather quickly, but start putting 80 words in this text file and it will start being an issue, i'm not even talking about 200-300 lines where mIRC would just start freezing to do the job, the more lines you have, the longer it will take.
Regex allow you to match severals string together, it avoids having to script the 'match', everything is concatenated to form a regular expression, and this way you avoid both loop: the loop over the lines in the file are handled because the regular expression itself represent "i want to match this, or this, or this, etc" where "this" is each line in the file. But also the loop over all the token in $1- because of the way regex works.
You probably have rarely seen a while loop lagging out mIRC because it's not everyday you need to loop over a lot of lines, that typically only happens when a database is involved and you just don't have huge database.
Anyway, the OP had already been using one single while loop (the second one being handled by $read itself, which is not how you used $read!) and said that he was looking for a better way. 
Since only the speed execution of the code can be considered better in this case, clearly you two nested while loop aren't better.
Note that a simple suggestion like using the undocumented $* was already a better solution in this case, it's faster than a while loop and could be used on $1- to avoid the loop on all tokens.
since i use it in my bot with a .txt that has many lines and it was tested in big messages and it scanned them in some milliseconds.
How much tokens and how many lines in the file?