-1

I'm currently coding a bot for Twitch.
Now I want to check each message for special characters and detect messages that have more than 20% special characters.

The message itself is a variable var msg and if the message should contain more than 20% special characters a command should be used to time out the user.

This is the event it should listen to:

event.on("chat", function(user, channel, message) {
        var msg = message.toLowerCase();
        var args = msg.split(" ");

        console.log("<"+user.color+" | "+user.username+" | "+user.special+"> <"+channel+"> "+message)
    });

Hope anyone can help me. It's my first, more or less, serious project in JavaScript.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
Kazuto
  • 158
  • 2
  • 15

1 Answers1

1

tl;dr Jsfiddle

Well, I don't know what do you call a special character, but let's say it's anything but stuff that appears in normal text:

//Regular expression that matches everything except specified
var regexp = /[^a-z0-9 ',\.:!\?]/ig;
//Get number of matches
var num_match = message.match(regexp);
num_match = num_match!=null?num_match.length:0;
//Percentage of unwanted characters:
var perctent_spec;
if(num_match!=null)
   perctent_spec = (num_match/message.length)*100; 
else 
   percent_spec = 0;

Of course, you could loop though two arrays instead:

var chars = message.split("");
var allowed = ["a", "b", "c" ... ];
var count = 0;
for(var i=0,l=chars.length; i<l; i++) {
    count++;
    for(var j=0,l2 = allowed.length; j<l2; j++) {
        if(chars[i]==allowed[i]) {
          count--;
          break;
        }
    }
}

But I have strong suspition that the loop approach would be slower than regular expression, which uses built-in functions right away.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Thanks, I tried the first option but for some reason it won't work. I can't format the code properly for some reasons. – Kazuto Sep 10 '14 at 00:07
  • Don't make assumptions about performance. Loops are highly optimised so might surprise you. It might be faster to specify the allowed characters as a range, then use [*charCodeAt*](http://ecma-international.org/ecma-262/5.1/#sec-15.5.4.5) to see if a character is within range as it removes one loop. – RobG Sep 10 '14 at 00:16
  • Oh, and if there are no matches, *num_match* will be *null* so you can do `if (!num_match)` or even `percent_spec = num_match? num_match/message.length*100 : 0`. ;-) – RobG Sep 10 '14 at 00:19
  • @RobG I wanted the code to be as verbose as possible. Though `!x` returns false for `x==null`, it's now not so obvious, that we're checking for null. As of loops, I was just lazy to check it on jsperf, so I made my assumption. – Tomáš Zato Sep 10 '14 at 00:25
  • @Kazuto "**Won't work**" is useless and empty sentence. If you want help, you should at least bother to provide some info. – Tomáš Zato Sep 10 '14 at 00:26
  • I tried to provide some info but the code won't get formatted properly. `event.on("chat", function(user, channel, message) { var msg = message.toLowerCase(); var args = msg.split(" "); var regexp = /[^a-z0-9 ',\.:!\?]/ig; var num_match = msg.match(regexp); var perctent_spec; if(num_match!=null) { percent_spec = (num_match/message.length)*100; client.say(channel, ".timeout "+user+" 600"); } else { percent_spec = 0; } console.log("<"+user.color+" | "+user.username+" | "+user.special+"> <"+channel+"> "+message) });` – Kazuto Sep 10 '14 at 00:29
  • What does mean *not formated properly*? What is the code you posted supposed to tell me? – Tomáš Zato Sep 10 '14 at 00:32
  • It is supposed to tell you the way I implemented your first option. I don't really know what's not working, I just know that if I try to post only @ or € nothing happens. I won't get timed out. – Kazuto Sep 10 '14 at 00:34
  • Just copy pasting my code won't do that. You need to read the code and use the data it produces (the variable `percent_spec` contains the percentage). I see you didn't even bother doing this. You know, if you want full code for your project, is it still *your* project? – Tomáš Zato Sep 10 '14 at 00:36
  • It's not that I didn't bother, it's more that I don't really undestand your code. I never really worked with JavaScript before, therefore it's hard for me to understand codes like this because I only know little what the syntaxes mean and do. – Kazuto Sep 10 '14 at 00:41
  • Well, how do you compare numbers in javascript? You need to compare generated percentage with `20`. And depending on result, you should kick the user or leave him be. – Tomáš Zato Sep 10 '14 at 00:46
  • I just looked up the operators for JavaScript and `if(percent_spec>=20) { client.say(channel, ".timeout "+user+" 600"); };` should work, or? – Kazuto Sep 10 '14 at 00:47
  • Buddy, this is not a chat. Yea, you figured it right. But you didn't need to ask if it's right, you can just test it. I don't like to be mean - but did you know that a moderator will have to come here and erase all these comments? – Tomáš Zato Sep 10 '14 at 00:59
  • Oh, sorry, there was an error in my code. There must be `message.match(regexp).length;`. – Tomáš Zato Sep 10 '14 at 01:00