JavaScript split string around emails - javascript

So I have this list of emails:
john.doe#doe.com
john.doe#doe.com
john.doe#doe.com
john.doe#doe.com
john.doe#doe.com
john.doe#doe.com
john.doe#doe.com
john.doe#doe.com
It comes through as a string, sometimes with a return character at the end of each line, sometimes it doesn't. All I want to be able to do is pull out each email from the string using regex.
So I've got this regex exp from here:
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
How do I get it to match many email addresses and return me each individual email?
I do not want to split on a return character, I can't always garauntee that it will be that character that will split the list up. These emails are pasted in from the users clipboard. If it were that easy, I wouldn't have asked ;)

It comes through as a string, with a return character at the end of
each line.
Then just split the string on newlines ?
var email_array = str.split("\n");

Here's a VERY simple way to do it.
/([^;:<>!?\n]+\#[^;:<>!?\n]+\.[^;:<>!?\n]+)/gmi
Explanation:
The [^;:<>!?\n] matches everything EXCEPT those characters. So [^;:<>!?\n]+ just means match everything but these as many times as needed.
Then match an # symbol.
Then match as many of NOT these ([^;:<>!?\n]) as needed again.
Then match a literal dot (.).
Then DON'T match these ([^;:<>!?\n]) again.
The gmis at the end are called flags. They mean:
g means global. Match this RegEx over and over.
m means multi-line. Don't stop at the end of the first line of emails.
i means insensitive. Don't worry about the upper and lower cases.
Demonstrations here: https://regex101.com/r/aC5cK2/1

So I have re work the answer to incorporate what #adeneo said:
$scope.pasteThis = function(e) {
var emails = e.clipboardData.getData('text/plain');
var emailArray = emails.split(/(\n|\s|,)/);
angular.forEach(emailArray, function (e) {
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+#[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
if (EMAIL_REGEXP.test(e)) {
if (!contains($scope.emailAddresses, e)) {
$scope.emailAddresses.push(e);
}
}
});
}
function contains(arr, el) {
var found = false;
angular.forEach(arr, function(e) {
if (e == el) {
found = true;
}
});
return found;
}
So EMAIL_REGEXP is from the Angular source code. I use that in other places so it is very appropriate to use it here (consistency).
This function makes sure that after the emails are split, each one is a valid email address. This means that no mess can get through.

Related

is there a way for the content.replace to sort of split them into more words than these?

const filter = ["bad1", "bad2"];
client.on("message", message => {
var content = message.content;
var stringToCheck = content.replace(/\s+/g, '').toLowerCase();
for (var i = 0; i < filter.length; i++) {
if (content.includes(filter[i])){
message.delete();
break
}
}
});
So my code above is a discord bot that deletes the words when someone writes ''bad1'' ''bad2''
(some more filtered bad words that i'm gonna add) and luckily no errors whatsoever.
But right now the bot only deletes these words when written in small letters without spaces in-between or special characters.
I think i have found a solution but i can't seem to put it into my code, i mean i tried different ways but it either deleted lowercase words or didn't react at all and instead i got errors like ''cannot read property of undefined'' etc.
var badWords = [
'bannedWord1',
'bannedWord2',
'bannedWord3',
'bannedWord4'
];
bot.on('message', message => {
var words = message.content.toLowerCase().trim().match(/\w+|\s+|[^\s\w]+/g);
var containsBadWord = words.some(word => {
return badWords.includes(word);
});
This is what i am looking at. the var words line. specifically (/\w+|\s+|[^\s\w]+/g);.
Anyway to implement that into my const filter code (top/above) or a different approach?
Thanks in advance.
Well, I'm not sure what you're trying to do with .match(/\w+|\s+|[^\s\w]+/g). That's some unnecessary regex just to get an array of words and spaces. And it won't even work if someone were to split their bad word into something like "t h i s".
If you want your filter to be case insensitive and account for spaces/special characters, a better solution would probably require more than one regex, and separate checks for the split letters and the normal bad word check. And you need to make sure your split letters check is accurate, otherwise something like "wash it" might be considered a bad word despite the space between the words.
A Solution
So here's a possible solution. Note that it is just a solution, and is far from the only solution. I'm just going to use hard-coded string examples instead of message.content, to allow this to be in a working snippet:
//Our array of bad words
var badWords = [
'bannedWord1',
'bannedWord2',
'bannedWord3',
'bannedWord4'
];
//A function that tests if a given string contains a bad word
function testProfanity(string) {
//Removes all non-letter, non-digit, and non-space chars
var normalString = string.replace(/[^a-zA-Z0-9 ]/g, "");
//Replaces all non-letter, non-digit chars with spaces
var spacerString = string.replace(/[^a-zA-Z0-9]/g, " ");
//Checks if a condition is true for at least one element in badWords
return badWords.some(swear => {
//Removes any non-letter, non-digit chars from the bad word (for normal)
var filtered = swear.replace(/\W/g, "");
//Splits the bad word into a 's p a c e d' word (for spaced)
var spaced = filtered.split("").join(" ");
//Two different regexes for normal and spaced bad word checks
var checks = {
spaced: new RegExp(`\\b${spaced}\\b`, "gi"),
normal: new RegExp(`\\b${filtered}\\b`, "gi")
};
//If the normal or spaced checks are true in the string, return true
//so that '.some()' will return true for satisfying the condition
return spacerString.match(checks.spaced) || normalString.match(checks.normal);
});
}
var result;
//Includes one banned word; expected result: true
var test1 = "I am a bannedWord1";
result = testProfanity(test1);
console.log(result);
//Includes one banned word; expected result: true
var test2 = "I am a b a N_N e d w o r d 2";
result = testProfanity(test2);
console.log(result);
//Includes one banned word; expected result: true
var test3 = "A bann_eD%word4, I am";
result = testProfanity(test3);
console.log(result);
//Includes no banned words; expected result: false
var test4 = "No banned words here";
result = testProfanity(test4);
console.log(result);
//This is a tricky one. 'bannedWord2' is technically present in this string,
//but is 'bannedWord22' really the same? This prevents something like
//"wash it" from being labeled a bad word; expected result: false
var test5 = "Banned word 22 isn't technically on the list of bad words...";
result = testProfanity(test5);
console.log(result);
I've commented each line thoroughly, such that you understand what I am doing in each line. And here it is again, without the comments or testing parts:
var badWords = [
'bannedWord1',
'bannedWord2',
'bannedWord3',
'bannedWord4'
];
function testProfanity(string) {
var normalString = string.replace(/[^a-zA-Z0-9 ]/g, "");
var spacerString = string.replace(/[^a-zA-Z0-9]/g, " ");
return badWords.some(swear => {
var filtered = swear.replace(/\W/g, "");
var spaced = filtered.split("").join(" ");
var checks = {
spaced: new RegExp(`\\b${spaced}\\b`, "gi"),
normal: new RegExp(`\\b${filtered}\\b`, "gi")
};
return spacerString.match(checks.spaced) || normalString.match(checks.normal);
});
}
Explanation
As you can see, this filter is able to deal with all sorts of punctuation, capitalization, and even single spaces/symbols in between the letters of a bad word. However, note that in order to avoid the "wash it" scenario I described (potentially resulting in the unintentional deletion of a clean message), I made it so that something like "bannedWord22" would not be treated the same as "bannedWord2". If you want it to do the opposite (therefore treating "bannedWord22" the same as "bannedWord2"), you must remove both of the \\b phrases in the normal check's regex.
I will also explain the regex, such that you fully understand what is going on here:
[^a-zA-Z0-9 ] means "select any character not in the ranges of a-z, A-Z, 0-9, or space" (meaning all characters not in those specified ranges will be replaced with an empty string, essentially removing them from the string).
\W means "select any character that is not a word character", where "word character" refers to the characters in ranges a-z, A-Z, 0-9, and underscore.
\b means "word boundary", essentially indicating when a word starts or stops. This includes spaces, the beginning of a line, and the end of a line. \b is escaped with an additional \ (to become \\b) in order to prevent javascript from confusing the regex token with strings' escape sequences.
The flags g and i used in both of the regex checks indicate "global" and "case-insensitive", respectively.
Of course, to get this working with your discord bot, all you have to do in your message handler is something like this (and be sure to replace badWords with your filter variable in testProfanity()):
if (testProfanity(message.content)) return message.delete();
If you want to learn more about regex, or if you want to mess around with it and/or test it out, this is a great resource for doing so.

Remove special character from the starting of a string and search # symbol.in javascript

I want to remove special characters from the starting of the string only.
i.e, if my string is like {abc#xyz.com then I want to remove the { from the starting. The string shoould look like abc#xyz.com
But if my string is like abc{#xyz.com then I want to retain the same string as it is ie., abc{#xyz.com.
Also I want to check that if my string has # symbol present or not. If it is present then OK else show a message.
The following demonstrates what you specified (or it's close):
var pat = /^[^a-z0-9]*([a-z0-9].*?#.*?$)/i; //pattern for optional non-alphabetic start followed by alphabetic, followed by '#' somewhere
var testString = "{abc#xyz.com"; //Try with {abcxyz.com for alert
arr = pat.exec(testString);
var adjustedString;
if (arr != null) { adjustedString = arr[1]; } //The potentially adjustedString (chopped off non-alphabetic start) will be in capture group 1
else { adjustedString = ""; alert(testString + " does not conform to pattern"); }
adjustedString;
I have used two separate regex objects to achieve what you require .It checks for both the conditions in the string.I know its not very efficient but it will serve your purpose.
var regex = new RegExp(/(^{)/);
var regex1 = new RegExp(/(^[^#]*$)/);
var str = "abc#gmail.com";
if(!regex1.test(str)){
if(regex.test(str))
alert("Bracket found at the beginning")
else
alert("Bracket not found at the beginning")
}
else{
alert("doesnt contain #");
}
Hope this helps

Javascript regular expression spaces check

I have a question for you that I can't seem to figure out on my own.
Let's say that I want to validate a users first name. Some can contain multiple parts like "John William" with a space in between. What I want to do is match the input to a regular expression that seeks out if the name contains any spaces at the beginning, or at the end.
Further more the regular expression should check if there are ONLY letters (a-z, both lower and upper case) in the name.
This is what I came up with so far:
/^\s+[A-z]+|[A-z]+\s+$/
But somehow this regular expression does not take any other characters (such as dash, underscore, ampersand, etc.) into notice. Basically all it does is tell me wether there are spaces at the beginning or at the end of the input.
Can anyone help me out here?
EDIT:
Here's the full code i'm using:
$(document).ready(function() {
$('#firstname, #lastname').bind('keyup blur', function() {
var _input = $(this);
var _illegal = Validate_Regexp(_input.val(), /^\s+[A-Za-z]+|[A-Za-z]+\s+$/);
if (_illegal == true) {
$("#"+_input.attr('id')+".validator").css({
'background-image' : 'url(./images/icons/bullet_red.png)',
});
} else {
$("#"+_input.attr('id')+".validator").css({
'background-image' : 'url(./images/icons/bullet_green.png)',
});
}
});
});
function Validate_Regexp($value, $regexp) {
return $regexp.test($value);
}
EDIT 2:
I'm going with Charlie's answer, however his answer forced me to have 2 parts of the name, instead of as much as I'd like.
I changed the code from:
var isLegal = /^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test(stringToTest);
to:
var isLegal = /^[a-zA-Z]+(\s[a-zA-Z]+)*?$/.test(stringToTest);
I noticed that you are checking for strings that are illegal. Let's turn it around and check for a string that is valid:
var isValid = /^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test(stringToTest);
Results:
/^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test("john doe"); // true
/^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test("john"); // true
/^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test("john d_oe"); // false
/^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test(" john doe "); // false
/^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test(" john doe"); // false
/^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test("john doe "); // false
/^[a-zA-Z]+(\s+[a-zA-Z]+)?$/.test("john "); // false
Translated to your existing code:
var isValid = Validate_Regexp(_input.val(), /^[a-zA-Z]+(\s+[a-zA-Z]+)?$/);
if (isValid) {
$("#"+_input.attr('id')+".validator").css({
'background-image' : 'url(./images/icons/bullet_blue.png)',
});
} else {
$("#"+_input.attr('id')+".validator").css({
'background-image' : 'url(./images/icons/bullet_red.png)',
});
}
You really don't care if there are leading or trailing spaces, or how many there are in between the names, all that stuff is very easy to manage without bothering the user.
So a suitable function might be:
function checkNames(s) {
// Remove excess spaces
s.replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' ');
// Check remaining content
return /[a-z]+ [a-z]+/i.test(s);
}
But note that names can be hyphenated and contain numbers (e.g. William Gates the 3rd) or letters other than those in the English alphabet. So usually you let users type whatever they want and just deal with the spaces.

alphanumeric regex javascript

I am having a problem to get the simple reges for alphanumeric chars only work in javascript :
var validateCustomArea = function () {
cString = customArea.val();
var patt=/[0-9a-zA-Z]/;
if(patt.test(cString)){
console.log("valid");
}else{
console.log("invalid");
}
}
I am checking the text field value after keyup events from jquery but the results are not expected, I only want alphanumeric charachters to be in the string
This regex:
/[0-9a-zA-Z]/
will match any string that contains at least one alphanumeric character. I think you're looking for this:
/^[0-9a-zA-Z]+$/
/^[0-9a-zA-Z]*$/ /* If you want to allow "empty" through */
Or possibly this:
var string = $.trim(customArea.val());
var patt = /[^0-9a-z]/i;
if(patt.test(string))
console.log('invalid');
else
console.log('valid');
Your function only checks one character (/[0-9a-zA-Z]/ means one character within any of the ranges 0-9, a-z, or A-Z), but reads in the whole input field text. You would need to either loop this or check all characters in the string by saying something like /^[0-9a-zA-Z]*$/. I suggest the latter.
I fixed it this way
var validateCustomArea = function () {
cString = customArea.val();
console.log(cString)
var patt=/[^0-9a-zA-Z]/
if(!cString.match(patt)){
console.log("valid");
}else{
console.log("invalid");
}
}
I needed to negate the regex

Why does this jQuery code not work?

Why doesn't the following jQuery code work?
$(function() {
var regex = /\?fb=[0-9]+/g;
var input = window.location.href;
var scrape = input.match(regex); // returns ?fb=4
var numeral = /\?fb=/g;
scrape.replace(numeral,'');
alert(scrape); // Should alert the number?
});
Basically I have a link like this:
http://foo.com/?fb=4
How do I first locate the ?fb=4 and then retrieve the number only?
Consider using the following code instead:
$(function() {
var matches = window.location.href.match(/\?fb=([0-9]+)/i);
if (matches) {
var number = matches[1];
alert(number); // will alert 4!
}
});
Test an example of it here: http://jsfiddle.net/GLAXS/
The regular expression is only slightly modified from what you provided. The global flag was removed, as you're not going to have multiple fb='s to match (otherwise your URL will be invalid!). The case insensitive flag flag was added to match FB= as well as fb=.
The number is wrapped in curly brackets to denote a capturing group which is the magic which allows us to use match.
If match matches the regular expression we specify, it'll return the matched string in the first array element. The remaining elements contain the value of each capturing group we define.
In our running example, the string "?fb=4" is matched and so is the first value of the returned array. The only capturing group we have defined is the number matcher; which is why 4 is contained in the second element.
If you all you need is to grab the value of fb, just use capturing parenthesis:
var regex = /\?fb=([0-9]+)/g;
var input = window.location.href;
var tokens = regex.exec(input);
if (tokens) { // there's a match
alert(tokens[1]); // grab first captured token
}
So, you want to feed a querystring and then get its value based on parameters?
I had had half a mind to offer Get query string values in JavaScript.
But then I saw a small kid abusing a much respectful Stack Overflow answer.
// Revised, cooler.
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)')
.exec(window.location.search);
return match ?
decodeURIComponent(match[1].replace(/\+/g, ' '))
: null;
}
And while you are at it, just call the function like this.
getParameterByName("fb")
How about using the following function to read the query string parameter in JavaScript:
function getQuerystring(key, default_) {
if (default_==null)
default_="";
key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var qs = regex.exec(window.location.href);
if(qs == null)
return default_;
else
return qs[1];
}
and then:
alert(getQuerystring('fb'));
If you are new to Regex, why not try Program that illustrates the ins and outs of Regular Expressions

Categories