Javascript Regex - sanitize string with whitelist - javascript

I have a very basic RegEx problem. I'm trying to sanitize an input field with a whitelist. I'm trying to only allow numbers and a decimal into my field. If a user types an invalid character, I want to strip it out of the input and replace the input with a clean string.
I can get it working with only numbers, but I can't get the decimal into the allowed pool of characters:
var sanitize = function(inputValue) {
var clean = "",
numbersOnly = /[^0-9]/g; // only numbers & a decimal place
if (inputValue) {
if (numbersOnly.test(inputValue)) {
// if test passes, there are bad characters
for (var i = 0; i < inputValue.length; i++) {
clean += (!numbersOnly.test(inputValue.charAt(i))) ? inputValue.charAt(i) : "";
}
if (clean != inputValue) {
makeInputBe(clean);
}
}
}
};
Working fiddle

Rather than looping your input character by character and validating each character you can do this for basic sanitizing operation:
var s = '123abc.48##'
s = s.replace(/[^\d.]+/g, '');
//=> 123.48
PS: This will not check if there are more than 1 decimal points in the input (not sure if that is the requirement.

Related

javascript indexof regex A-Za-z0-9 always returns false

I have created a JS fiddle https://jsfiddle.net/95r110s9/#&togetherjs=Emdw6ORNpc
HTML
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />
JS
validateinputentries(){
landlordstreetaddress2 = document.getElementById('landlordstreetaddress2').value;
goodcharacters = "/^[a-zA-Z0-9#.,;:'\s]+$/gi";
for (var i = 0; i < landlordstreetaddress2.length; i++){
if (goodcharacters.indexOf(landlordstreetaddress2.charAt(i)) != -1){
console.log('Character is valid');
}
}
}
Its pulling the value from an input and running an indexOf regex expression with A-Z a-z and 0-9 with a few additional characters as well.
The problem is that it works with the entry of BCDEFG...etc and 12345...etc, but when I type "A" or "Z" or "0" or "1", it returns incorrectly.
I need it to return the same with 0123456789, ABCDEF...XYZ and abcdef...xyz
I should point out that the below does work as intended:
var badcharacters = "*|,\":<>[]`\';#?=+/\\";
badcharacter = false;
//firstname
for (var i = 0; i < landlordfirstname.value.length; i++){
if (badcharacters.indexOf(landlordfirstname.value.charAt(i)) != -1){
badcharacter = true;
break;
}
if(landlordfirstname.value.charAt(0) == " "){
badcharacter = true;
break;
}
}
String.prototype.indexOf()
The indexOf() method returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex. Returns -1 if the value is not found.
So, you're trying to search this value "/^[a-zA-Z0-9#.,;:'\s]+$/gi" which "never" will be found in the entered string.
You actually want to test that regexp against the entered value.
/^[a-zA-Z0-9#.,;:'\s]+$/gi.test(landlordstreetaddress2)
function validateinputentries() {
var landlordstreetaddress2 = document.getElementById('landlordstreetaddress2').value;
if (/^[a-zA-Z0-9#.,;:'\s]+$/gi.test(landlordstreetaddress2)) {
console.log('Characters are valid');
} else {
console.log('Characters are invalid');
}
}
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />
You're trying to combine two different methods of testing a string -- one way is with a regex; the other way is by checking each character against a list of allowed characters. What you've wound up with is checking each character against a list of what would have been a regex, if you hadn't declared it as a string.
Those methods conflict with each other; you need to pick one or the other.
Check each character:
This is closest to what you were attempting. You can't use character ranges here (like a-zA-Z) as you would in a regex; you have to spell out each allowed character individually:
var validateinputentries = function() {
var address = document.getElementById('landlordstreetaddress2').value;
var goodcharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#.,;:' ";
var badcharactersfound = false;
for (var i = 0; i < address.length; i++) {
if (goodcharacters.indexOf(address.charAt(i)) == -1) {
badcharactersfound = true;
console.log("not allowed: ", address.charAt(i));
}
}
if (badcharactersfound) {
// Show validation error here
}
}
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />
Regular Expressions
The regex version is much simpler, because the regular expression is doing most of the work. You don't need to step through the string, just test the whole string against the regex and see what comes out. In this case you're looking to see if the input contains any characters that aren't allowed, so you want to use the character exception rule: [^abc] will match any character that is not a, b, or c. You don't want to anchor the match to the beginning or the end of the string, as you were doing with the initial ^ and the trailing $; and you can leave out the + because you don't care if there are sequential bad characters, you just care if they exist at all.
var validateinputentries = function() {
var address = document.getElementById('landlordstreetaddress2').value;
var regex = new RegExp("[^a-zA-Z0-9#.,;:'\\s]","g")
var badcharactersfound = address.match(regex);
// or the above two lines could also have been written like this:
// var bad = address.match(/[^a-zA-Z0-9#.,;:'\s]/g)
// In either case the "g" operator could be omitted; then it would only return the first bad character.
if (badcharactersfound) {
console.log("Not allowed: ", badcharactersfound);
}
}
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />

How to replace US phone number format onkeypress and limit the length?

How to limit the length of numbers when key is pressed:
var regx = /^[0-9]+$/;
$("#login_email_or_mob").keyup(function(){
var mob_or_email = $("#login_email_or_mob").val();
if(regx.test(mob_or_email)) {
if(mob_or_email.length==11){
this.value = this.value.replace(/(\d{3})\-?(\d{3})\-?(\d{4})/,'$1-$2-$3');
}
In your code, you're matching the first ten characters and replacing them only. The other characters remain intact. To change this behaviour, select them as well with .*:
if(regx.test(this.value)) {
if(this.value.length==11){
this.value = this.value.replace(/(\d{3})\-?(\d{3})\-?(\d{4}).*/,'$1-$2-$3'));
}
}

Regex to check only numbers(negative and positive)

There is an input field on the JSP where users can enter numbers(negative and positive both).
I've a JS function that checks on each key up event on the input field is not a number, it should replace it with blank.
var txt = $(elem).val();
if(!(txt.match(/^-?[0-9]*$/))) {
$(elem).val(txt.replace(/^-?[0-9]+/g, ''));
}
My if condition is working fine, but I'm not able to create a regex for replacing.
Edit: question was clarified that only numeric values should be accepted
You could just check that the number is < 0 after removing all non-numeric characters:
// remove all non-numeric characters
var txt = $(elem).val().replace(/[^\-0-9]/g, '');
if(parseInt(txt) < 0)){
// negative number
}
To check if a number do this
var txt = $(elem).val();
if (!isNAN(txt) && parseInt(txt) >=0) {
//validate
} else {
// Invalidate
}

How to regex match entire string instead of a single character

I am trying to implement "alpha" validation on Arabic alphabet characters input, using the JavaScript regex /[\u0600-\u06FF]/ as instructed in this post. I want to accept only Arabic alphabet characters and spaces.
Now the problem is it gives the following result:
r = /[\u0600-\u06FF]/
r.test("abcd") // false - correct
r.test("##$%^") // false - correct
r.test("س") // true - correct
r.test("abcd$$#5س") // true - should be false
r.test("abcdس") // true - should be false
If a single matching character is given, then it is classifying the whole input as acceptable, even if the rest of the input is full of unacceptable chars. What regex should I be using instead?
You need to add ^ and $ anchors to the regular expression, as well as a + to allow multiple characters.
Try this:
/^[\u0600-\u06FF]+$/
I'm not sure if "Arabic spaces" that you mentioned are included in the character range there, but if you want to allow white space in the string then just add a \s inside the [] brackets.
You can explicitly allow some keys e-g: numpad, backspace and space, please check the code snippet below:
function restrictInputOtherThanArabic($field)
{
// Arabic characters fall in the Unicode range 0600 - 06FF
var arabicCharUnicodeRange = /[\u0600-\u06FF]/;
$field.bind("keypress", function(event)
{
var key = event.which;
// 0 = numpad
// 8 = backspace
// 32 = space
if (key==8 || key==0 || key === 32)
{
return true;
}
var str = String.fromCharCode(key);
if ( arabicCharUnicodeRange.test(str) )
{
return true;
}
return false;
});
}
// call this function on a field
restrictInputOtherThanArabic($('#firstnameAr'));

Finding uppercase characters within a string

I am trying to write a function that decryptes an encrypted message that has uppercase letters (showing its a new word) and lower case characters (which is the word itself). The function needs to search through the encrypted message for all the uppercase letters and then returns the uppercase character along with lower case that follows it. I have been given a function to call on within the decrypt function:
function isUpperCase(aCharacter)
{
return (aCharacter >= 'A') && (aCharacter <= 'Z');
}
I was thinking that I would search through the word for all the uppercase characters first and assign that as a new string. I could then do while loop that will pick up each of the letters in the new string and then search for the lower case characters that are next to it in the old string.
However, I am completely stuck at the first part - I cant even work out the structured English.
The code is:
encryptMessage is a string containing uppercase and lowercase characters
indexCharacter is used at a later date for another function
upperAlphabet - alphabet of uppercase characters - used later
lowerAlphabet - alphabet lowercase characters - used later
The function:
function decryptMessage(encryptMessage, indexCharacter, upperAlphabet, lowerAlphabet)
{
var letter
var word = "";
for (var count = 0; count < encryptMessage.length; count = count +1);
{
letter = encryptMessage.charAt(count)
if (isUpperCase(letter));
{
word = word + letter;
}
document.write(word); //this is just to test to see if it returns the uppercase - I would use the return word
}
The above just doesnt seem to work, so I cant even continue with the rest of the code. Can anyone help me identify where i have gone wrong - have I completely gone the wrong direction with this anyway, reading it back I dont think it really makes much sense ?? Its a very basic code, I have only learnt, for, while loops - if and else functions really, i am just soooooo stuck.
thanks in advance for your advice :-)
Issy
I'm not too sure I follow, but you can strip using the replace method and regular expressions
var str = 'MaEfSdsfSsdfsAdfssdGsdfEsdf';
var newmsg = str.replace(/[a-z]/g, '');
var old = str.replace(/[A-Z]/g, '');
In this case, newmsg = 'MESSAGE'.
A simple condition for checking uppercase characters in a string would be...
var str = 'aBcDeFgHiJkLmN';
var sL = str.length;
var i = 0;
for (; i < sL; i++) {
if (str.charAt(i) === str.charAt(i).toUpperCase()) {
console.log('uppercase:',str.charAt(i));
}
}
/*
uppercase: B
uppercase: D
uppercase: F
uppercase: H
uppercase: J
uppercase: L
uppercase: N
*/
EDIT
String input = "ThisIsASecretText";
for(int i = 0; i < input.Length; i++)
{
if(isUpperCase(input.charAt(i))
{
String nextWord = String.Empty;
for(int j = i; j < input.Length && !isUpperCase(input.charAt(j)); j++)
{
nextWord += input.charAt(j);
i++;
}
CallSomeFunctionWithTheNextWord(nextWord);
}
}
The following calls would be made:
CallSomeFunctionWithTheNextWord("This");
CallSomeFunctionWithTheNextWord("Is");
CallSomeFunctionWithTheNextWord("A");
CallSomeFunctionWithTheNextWord("Secret");
CallSomeFunctionWithTheNextWord("Text");
You can do the same thing with much less code using regular expressions, but since you said that you are taking a very basic course on programming, this solution might be more appropriate.
Use Unicode property escapes, in particular the "Lu" General Property Category, which matches uppercase. There are categories for numbers, punctuation, currency, and just about any other category of character you might be interested in.
In the example below, the "u" modifier enables Unicode matching.
"HeLlo WoRld".match(/\p{Lu}/gu) // [ 'H', 'L', 'W', 'R' ]
I would rather use Array.reduce as follows:
say, example sample = 'SampleStringAsFollows';
let capWord = [...sample].reduce((caps,char) => (char.match(/[A-Z]/)) ? caps + char : caps,'');
console.log(capWord); //SSAF
capWord will be a string of CAPITAL CHARACTERS and will also tackle the boundary cases where in the string may contain special characters.
Please Use Below code to get first Capital letter of the sentence :
Demo Code
var str = 'i am a Web developer Student';
var sL = str.length;
var i = 0;
for (; i < sL; i++) {
if (str.charAt(i) != " ") {
if (str.charAt(i) === str.charAt(i).toUpperCase()){
console.log(str.charAt(i));
}
}
}

Categories