StrawberryKitty, there's nothing wrong with the code Horstl provides for you. With a little revamp of it, here is all you need to replace all the characters with the underscore as you've mentioned:
on $*:text:/[\41-\47\50-\57\72-\77\100\133-\136\140\173-\176]/:#: {
.msg # $regsubex($1-,/[\41-\47\50-\57\72-\77\100\133-\136\140\173-\176]/g,_)
}
This does exactly the same thing compared to your example of using $replace(), which takes longer and more bytes. Best yet, even in a sentence that consists of any of those characters will be replaced with the underscore. Other normal text won't be effected.
I'll suggest that you use a custom text event instead of the default one to display the result. A custom text event will look like this:
on ^$*:text:/[\41-\47\50-\57\72-\77\100\133-\136\140\173-\176]/:#: {
echo -bfilmrt # $+(<,$nick(#,$nick).pnick,>) $regsubex($1-,/[\41-\47\50-\57\72-\77\100\133-\136\140\173-\176]/g,_) | haltdef
}
You might want to cover the on action or notice event if needed.