It's possible, but the number of badwords is going to be a lot more limited than using a hashtable, since variables have a limit of about 950 characters including the variable name, the spaces on either side of the = sign and the = sign.
Before we get into making changes like that, which in my opinion for something like this, would be going backwards, can you post an example of an entry from the hash table.
I see that you load/store the hash table from/to a file called bad.away.hsh
That file, if brought up in a word processor (eg: notepad), will have the item name on one line, then the data for the item on the next.
If you would post a small example (2 or 3 entries should be sufficient), then I'll review that information to see if it might be organized better, or if maybe the organization is your problem.
Going through your code more carefully, I think I found a better way of doing this. Here's the re-write I came up with
P.S.: This has been tested to a limited extent.
raw 301:*:{
if (%away != off) && ($2 !isop #chat) {
var %a = 1, %b = $numtok($3-,32)
while %a <= %b {
if $hget(bad.away,$gettok($3-,%b,32)) {
ban -ku600 #chat $2 2 14Offensive Away Msg
%a = %b
}
inc %a
}
return $regsubex($1-,/\b( $+ %away $+ )\b/gi,$str(*,$len(\t)))
}
haltdef
}
on *:start:{
if !$hget(bad.away) { .hmake bad.away 10 }
if $exists(bad.away.hsh) { .hload bad.away bad.away.hsh }
}
on *:exit:{
.hsave -o bad.away bad.away.hsh
}
on *:disconnect:{
.hsave -o bad.away bad.away.hsh
}
alias bad.away {
if !$1 { .notice $nick No word specified }
else { .hadd -m bad.away $1 $iif($hget(bad.away,$1),$false,$true) }
}