Problems with dynamic RegExp construction in Javascript - javascript

This method is to prevent users from entering anything but numbers and "allowed characters." Allowed characters are passed as the parameter allowedchars.
So far, the method prevents number entries but the allowedchars doesn't work (tried with passing "-" (hyphen) and "." (period)). So I'm assuming my dynamic regex construction isn't correct. Help?
Thanks in advance!
numValidate : function (evt, allowedchars) {
var theEvent, key, regex,
addToRegex = allowedchars;
theEvent = evt || window.event;
key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = new RegExp('/^[0-9' + addToRegex + ']$/');
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) {
theEvent.preventDefault();
}
}
}
(ps. jQuery solutions are fine too)

1. When you construct via new RegExp, there's no need to include the surrounding /s.
var regex = new RegExp('^[0-9' + addToRegex + ']$');
2. But if addToRegex contains ] or -, the resulting regex may become invalid or match too much. So you need to escape them:
var regex = new RegExp('^[0-9' + addToRegex.replace(/([\-\]])/g, '\\$1') + ']$');
3. But since you are checking against 1 character anyway, it may be easier to avoid regex.
var pass = ("0123456789" + addToRegex).indexOf(key);
if (pass == -1) {
...

Related

Regular Expression Pattern matching issue

Not a lot of experience in RegEx stuff.
I have the following in java script which works perfectly fine.
The following pattern is used allow only alpha numeric
var valid = /^[A-Za-z0-9]+$/.test("a"); // returns true
var valid = /^[A-Za-z0-9]+$/.test("#"); // returns false
I am using the pattern part "^[A-Za-z0-9]" in some other places of the code and was asked to use the part "^[A-Za-z0-9]" in a variable and use it so that it is not repetitive. The following is a modification to the above:
var regExPart= "^[A-Za-z0-9]";
var regExString = ("/" + regExPart+ "+$/".replace(/\"/g, "")); // replacing the quotes
var regExp = new RegExp(regExString); // results in /^[A-Za-z0-9]+$/
var valid = regExp.test(charValue); // charValue could be any keyvalue "a" or "#"
//the above returns false for "a"
//the above returns false for "#"
I am writing this in a keypress event to allow only alpha numeric
keypressValidation: function (e) {
var charCode = (e.which) ? e.which: event.keyCode;
var charValue = String.fromCharCode(charCode);
var valid = return /^[A-Za-z0-9]+$/.test(charValue);
if (!valid)
{
//prevent default (don't allow/ enter the value)
}
Not sure why. What am I missing in this. Need to return true for "a" and false for "#" for both the approaches. Any help/ suggestion would be of great help. Thank in advance.
For the RegExp class constructor, you do not need to specify forward slashes /.
var regExPart= "^[A-Za-z0-9]";
var regExp = new RegExp(regExPart + "+$"); // results in /^[A-Za-z0-9]+$/
console.log('a', regExp.test('a'))
console.log('#', regExp.test('#'))
It is not a must to contain '/'s in regexp
new RegExp("^[0-9a-zA-Z]$").test('a')
return true
new RegExp("^[0-9a-zA-Z]$").test('#')
return false
So just do
var rex="^[0-9a-zA-Z]$"
And you can use it anywhere. Tested in Chrome console.
I've made an example using your regex of what it should do, i think the way you were building your regex was not helping. You don't need to create a string and then create a new regex object , you can use /regex part/.
Anyways here is a working example.
function keypress(e) {
// Get the current typed key
var keynum = e.key;
// this regex only allow character between a and z and 0 and 9
var regex = /^[a-zA-Z0-9]+$/;
// we check if the current key matches our regex
if(!keynum.match(regex) ) {
// it doesn't ? well we stop the event from happening
e.preventDefault();
}
}
<input type="text" onkeypress="keypress(event)">

Regex match all strings containing a given series of letters or digits

I have a search box and i need to grab the value of this search and match all DIV which data-* value is starting with the search value.
Cases:
Search value: 201
Should match: data-year="2011", data-year="2012", data-year="2013"
Should fail: data-year="2009", data-year="2001"
This is what i come up with so far:
\\b(?=\\w*[" + token + "])\\w+\\b
token is a dynamic value from the search box. Therefore i need to use RegExp
This is working but it match all the value which contain 2 or 0 or 1 (for my understanding). so 2009 is valid match as well. :/
I also try to add the caret at the beginning in order to match the characthers just at the beginning of the world but clearly i'm missing something here:
^\\b(?=\\w*[" + token + "])\\w+\\b
The whole code is:
var token = '200'; // should fail
var tokenTwo = '201'; // shoudl work
var dataAtt = $('#div').data('year').toString();
var regexExpression ="^\\b(?=\\w*\\d*[" + token + "])\\w+\\d+\\b";
var regEXPRES = "^.*" + token + ".*$";
var regex = new RegExp(regexExpression, "i");
if( dataAtt.match(regex) ){
console.log(dataAtt);
alert('yey!!!');
} else {
alert('nope!! )')
}
and here is the JsFiddle http://jsfiddle.net/tk5m8coo/
p.s. I shouldn't have any cases where token is precede or follow by other characters, but if anyone as idea how to check also this, would be great. Just in case of any typo like s2015.
Problem is that you're putting your search value inside a character class when you enclose your regex by wrapping around [...].
You also don't need a lookahead. You can just use:
var regex = new RegExp("\\b\\w*" + value + "\\w*\\b");
To make sure search value is matched within a full word. (\w includes digits also so no need to use \d).
Full code:
var value = '20'; //token
var html = $("#div").html(); //data.()
var dataAtt = $('#div').data('year').toString();
var regex = new RegExp("\\b\\w*" + value + "\\w*\\b");
if( dataAtt.match(regex) ){
console.log(dataAtt + " matched");
} else {
console.log('nope')
}
Updated JS Fiddle
Or you can use indexOf():
var value = '20';
var html = $("#div").html();
var dataAtt = $('#div').data('year').toString();
if( dataAtt.indexOf(value) >= 0 ){
console.log('yey!!!');
} else {
console.log('nein!! )')
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id ="div" data-year="2015">
what bozo where 2015
</div>
Your regex is using a character class which will match any of the characters inside the square brackets. Remove the square brackets:
^\\b(?=\\w*" + token + ".*)\\w+\\b

allow space between two word using regular expression

I need to block special character except comma. So I am using code given below. Its is working but it is also removing space between two words. fiddle
var chars =/[(,\/\w)]/i;
$('input').keyup(function(e) {
var value = this.value;
var char = value[value.length-1];
if(char !== ' ' || value.length==1 || (value[value.length-2]!==' ' )){
if (!chars.test(char)) {
$(this).val(value.substring(0, value.length-1));
}
}
});
In terms of usability, manipulating the user's input as they're typing can be very frustrating. In addition, if the user types fast enough it doesn't work anyway (as mentioned by Daniel Knippers, above)
A better bet would be to validate the user's input and let them know in real-time if the input is invalid.
Try this code:
var regex =/^[\w\s\,]*$/i;
$('input').keyup(function(e) {
var message = regex.test(this.value) ? "" : "Error";
$('#message').html(message);
});
jsFiddle version
as far as i am understood, you wants that space should be allowed in txt box
so,
here is your ANSWER
you need to add space after \w
var chars =/[(,\/\w )]/i;
$('input').keyup(function(e) {
var value = this.value;
var char = value[value.length-1];
if(char !== ' ' || value.length==1 || (value[value.length-2]!==' ' )){
if (!chars.test(char)) {
$(this).val(value.substring(0, value.length-1));
}
}
});
please note that i have added space after \w, so the regexp is var chars =/[(,\/\w )]/i;

check if string is equal to a word and a number

I have an object that contains a string as a property. I want to check that this property is not equal to some word, followed by a space and a number. For instance, something like this:
var TheWordToCheck = "SomeWord";
if (TheObject['SomeProperty'] !== (TheWordToCheck + ' ' + 2)) {...}
if (TheObject['SomeProperty'] !== (TheWordToCheck + ' ' + 3)) {...}
In this example, the code checks for only "SomeWord 2" and "SomeWord 3". How can I simplify this where it checks any numbers?
Thanks.
You could use a regex and the match() method (untested)
var reg = new RegExp("^"+TheWordToCheck+"\\s\\d$")
if (!TheObject['SomeProperty'].match(reg) {...
FIDDLE
depends on the range of numbers you need to check, if it is static or is less than a maximum value, you can use a loop and append the loop variable with the string and check
for (var i=0;i<maxNumber;i++)
{
if (TheObject['SomeProperty'] !== (TheWordToCheck + ' ' + i)) {...
break;
}
}
or you can use regex as suggested in the comments
You can use a regular expression to check this:
var TheWordToCheck = "SomeWord";
var TheObject = {
"SomeProperty": "SomeWord 100"
};
var pattern = new RegExp(TheWordToCheck + ' \\d', 'g');
if (TheObject['SomeProperty'].match(pattern) != null) { ... }
Note that you have to do the backslashes twice in order to make sure that the first one is escaped in the pattern. You should also use the RegEx constructor in order to be able to use a variable in your pattern.

Remove all dots except the first one from a string

Given a string
'1.2.3.4.5'
I would like to get this output
'1.2345'
(In case there are no dots in the string, the string should be returned unchanged.)
I wrote this
function process( input ) {
var index = input.indexOf( '.' );
if ( index > -1 ) {
input = input.substr( 0, index + 1 ) +
input.slice( index ).replace( /\./g, '' );
}
return input;
}
Live demo: http://jsfiddle.net/EDTNK/1/
It works but I was hoping for a slightly more elegant solution...
There is a pretty short solution (assuming input is your string):
var output = input.split('.');
output = output.shift() + '.' + output.join('');
If input is "1.2.3.4", then output will be equal to "1.234".
See this jsfiddle for a proof. Of course you can enclose it in a function, if you find it necessary.
EDIT:
Taking into account your additional requirement (to not modify the output if there is no dot found), the solution could look like this:
var output = input.split('.');
output = output.shift() + (output.length ? '.' + output.join('') : '');
which will leave eg. "1234" (no dot found) unchanged. See this jsfiddle for updated code.
It would be a lot easier with reg exp if browsers supported look behinds.
One way with a regular expression:
function process( str ) {
return str.replace( /^([^.]*\.)(.*)$/, function ( a, b, c ) {
return b + c.replace( /\./g, '' );
});
}
You can try something like this:
str = str.replace(/\./,"#").replace(/\./g,"").replace(/#/,".");
But you have to be sure that the character # is not used in the string; or replace it accordingly.
Or this, without the above limitation:
str = str.replace(/^(.*?\.)(.*)$/, function($0, $1, $2) {
return $1 + $2.replace(/\./g,"");
});
You could also do something like this, i also don't know if this is "simpler", but it uses just indexOf, replace and substr.
var str = "7.8.9.2.3";
var strBak = str;
var firstDot = str.indexOf(".");
str = str.replace(/\./g,"");
str = str.substr(0,firstDot)+"."+str.substr(1,str.length-1);
document.write(str);
Shai.
Here is another approach:
function process(input) {
var n = 0;
return input.replace(/\./g, function() { return n++ > 0 ? '' : '.'; });
}
But one could say that this is based on side effects and therefore not really elegant.
This isn't necessarily more elegant, but it's another way to skin the cat:
var process = function (input) {
var output = input;
if (typeof input === 'string' && input !== '') {
input = input.split('.');
if (input.length > 1) {
output = [input.shift(), input.join('')].join('.');
}
}
return output;
};
Not sure what is supposed to happen if "." is the first character, I'd check for -1 in indexOf, also if you use substr once might as well use it twice.
if ( index != -1 ) {
input = input.substr( 0, index + 1 ) + input.substr(index + 1).replace( /\./g, '' );
}
var i = s.indexOf(".");
var result = s.substr(0, i+1) + s.substr(i+1).replace(/\./g, "");
Somewhat tricky. Works using the fact that indexOf returns -1 if the item is not found.
Trying to keep this as short and readable as possible, you can do the following:
JavaScript
var match = string.match(/^[^.]*\.|[^.]+/g);
string = match ? match.join('') : string;
Requires a second line of code, because if match() returns null, we'll get an exception trying to call join() on null. (Improvements welcome.)
Objective-J / Cappuccino (superset of JavaScript)
string = [string.match(/^[^.]*\.|[^.]+/g) componentsJoinedByString:''] || string;
Can do it in a single line, because its selectors (such as componentsJoinedByString:) simply return null when sent to a null value, rather than throwing an exception.
As for the regular expression, I'm matching all substrings consisting of either (a) the start of the string + any potential number of non-dot characters + a dot, or (b) any existing number of non-dot characters. When we join all matches back together, we have essentially removed any dot except the first.
var input = '14.1.2';
reversed = input.split("").reverse().join("");
reversed = reversed.replace(\.(?=.*\.), '' );
input = reversed.split("").reverse().join("");
Based on #Tadek's answer above. This function takes other locales into consideration.
For example, some locales will use a comma for the decimal separator and a period for the thousand separator (e.g. -451.161,432e-12).
First we convert anything other than 1) numbers; 2) negative sign; 3) exponent sign into a period ("-451.161.432e-12").
Next we split by period (["-451", "161", "432e-12"]) and pop out the right-most value ("432e-12"), then join with the rest ("-451161.432e-12")
(Note that I'm tossing out the thousand separators, but those could easily be added in the join step (.join(','))
var ensureDecimalSeparatorIsPeriod = function (value) {
var numericString = value.toString();
var splitByDecimal = numericString.replace(/[^\d.e-]/g, '.').split('.');
if (splitByDecimal.length < 2) {
return numericString;
}
var rightOfDecimalPlace = splitByDecimal.pop();
return splitByDecimal.join('') + '.' + rightOfDecimalPlace;
};
let str = "12.1223....1322311..";
let finStr = str.replace(/(\d*.)(.*)/, '$1') + str.replace(/(\d*.)(.*)/, '$2').replace(/\./g,'');
console.log(finStr)
const [integer, ...decimals] = '233.423.3.32.23.244.14...23'.split('.');
const result = [integer, decimals.join('')].join('.')
Same solution offered but using the spread operator.
It's a matter of opinion but I think it improves readability.

Categories

Resources