Regular expression to match certain string pattern - javascript

I have string patterns like name1|value1, name1|value1,name2|value2, name1| and name1|value1,. I have to have Regular expression to find the given pattern is true or false
Input and output would be
"name1|value1" -> true
"name1|value1,name2|value2" -> true
"name1|" -> false
"name1|value1," -> false
"name1|value1,name2" -> false
"name1|value1,name2|" -> false

Pretty simple: ^\w+\|\w+(,\w+\|\w+)*$
The first portion, ^\w+\|\w+ looks to make sure the string starts with at least 1 completed name|value pair.
Then the second portion, (,\w+\|\w+)* says that same pattern may repeat infinitely as long as there is a comma between the first pair and all subsequent pairs. (Although, the asterisk quantifies that the second portion of the pattern may not occur at all.)
Finally the $ says that the string must end matching this pattern. (I.e., this pattern cannot only match part of the string. It must match the entire string because of the ^ and $.)
To format this pattern for javascript, simply throw a forward slashes on both ends, so: /^\w+\|\w+(,\w+\|\w+)*$/ The pattern should not require any flags.
It is worth noting, if you need to match more complex names/values that are outside the character range of \w, then you should replace all \ws with [Some Character Set(s)].

If your have multiple pairs to check, you can apply your regex on splitted string elements with an every function:
isValidPairs = function(str) {
return str.split(',').every(function(elt) {
return /^\w+\|\w+$/.test(elt);
});
}
pairsArr = ["nam1|val1", "nam1|val1,name2|val2", "nam1|", "nam1|val1,", "nam1|val1,name", "nam1|val1,name|"];
pairsArr.forEach(function(str) {
console.log('%s: %s:', str, isValidPairs(str));
});

Related

JavaScript regex inline validation for basic calculation string with one operator

I've written a basic 2 operand calculator app (+ - * /) that uses a couple of inline regex validations to filter away invalid characters as they are typed.
An example looks like:
//check if operator is present
if(/[+\-*\/]/.test(display1.textContent)){
//validate the string each time a new character is added
if(!/^\d+\.?\d*[+\-*\/]?\d*\.?\d*$/.test(display1.textContent)){
console.log('invalid')
return false
}
//validate the string character by character before operator
} else {
if(!/^\d+\.?\d*$/.test(display1.textContent)){
console.log('invalid')
return false
}
}
In the above, a valid character doesn't return false:
23.4x0.00025 (no false returned and hence the string is typed out)
But, if an invalid character is typed the function returns false and the input is filtered away:
23.4x0.(x) x at the end returns a false so is filtered (only one operator allowed per calculation)
23.4x0. is typed
It works pretty well but allows for the following which I would like to deal with:
2.+.1
I would prefer 2.0+0.1
My regex would need an if-then-else conditional stating that if the current character is '.' then the next character must be a number else the next char can be number|.|operator. Or if the current character is [+-*/] then the next character must be a number, else the next char can be any char (while following the overall logic).
The tricky part is that the logic must process the string as it is typed character by character and validate at each addition (and be accurate), not at the end when the string is complete.
if-then-else regex is not supported in JavaScript (which I think would satisfy my needs) so I need to use another approach whilst remaining within the JS domain.
Any suggestions about this specific problem would be really helpful.
Thanks
https://github.com/jdineley/Project-calculator
Thanks #trincot for the tips using capturing groups and look around. This helped me write what I needed:
https://regex101.com/r/khUd8H/1
git hub app is updated and works as desired. Now just need to make it pretty!
For ensuring that an operator is not allowed when the preceding number ended in a point, you can insert a positive look behind in your regex that requires the character before an operator to always be a digit: (?<=\d)
Demo:
const validate = s => /^(\d+(\.\d*)?((?<=\d)[+*/-]|$))*$/.test(s);
document.querySelector("input").addEventListener("input", function () {
this.style.backgroundColor = validate(this.value) ? "" : "orange";
});
Input: <input>

Formatting in Javascript

I have a question related to formatting strings.
User should parse a string in the Format XX:XX.
if the string parsed by user is in the format XX:XX i need to return true,
else false:
app.post('/test', (req, res) => {
if (req.body.time is in the format of XX:XX) {
return true
} else {
return false
}
});
You can use the RegExp.test function for this kind of thing.
Here is an example:
var condition = /^[a-zA-Z]{2}:[a-zA-Z]{2}$/.test("XX:XX");
console.log("Condition: ", condition);
The regex that I've used in this case check if the string is composed from two upper or lower case letters fallowed by a colon and other two such letters.
Based on your edits it seems that you're trying to check if a string represents an hour and minute value, if that is the case, a regex like this will be more appropriate /^\d{2}:\d{2}$/. This regex checks if the string is composed of 2 numbers fallowed by a colon and another 2 numbers.
The tool you're looking for is called Regular Expressions.
It is globally supported in almost every development platform, which makes it extremely convenient to use.
I would recommend this website for working out your regular expressions.
/^[a-zA-Z]{2}:[a-zA-Z]{2}&/g is an example of a Regular Expression that will take any pattern of:
[a-zA-Z]{2} - two characters from the sets a-z and A-Z.
Followed by :
Followed by the same first argument. Essentially, validating the pattern XX:XX. Of course, you can manipulate it as to what you want to allow for X.
^ marks the beginning of a string and $ marks the end of it, so ASD:AS would not work even though it contains the described pattern.
try using regex
var str = "12:aa";
var patt = new RegExp("^([a-zA-Z]|[0-9]){2}:([a-zA-Z]|[0-9]){2}$");
var res = patt.test(str);
if(res){ //if true
//do something
}
else{}

javascript regex insert new element into expression

I am passing a URL to a block of code in which I need to insert a new element into the regex. Pretty sure the regex is valid and the code seems right but no matter what I can't seem to execute the match for regex!
//** Incoming url's
//** url e.g. api/223344
//** api/11aa/page/2017
//** Need to match to the following
//** dir/api/12ab/page/1999
//** Hence the need to add dir at the front
var url = req.url;
//** pass in: /^\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var re = myregex.toString();
//** Insert dir into regex: /^dir\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var regVar = re.substr(0, 2) + 'dir' + re.substr(2);
var matchedData = url.match(regVar);
matchedData === null ? console.log('NO') : console.log('Yay');
I hope I am just missing the obvious but can anyone see why I can't match and always returns NO?
Thanks
Let's break down your regex
^\/api\/ this matches the beginning of a string, and it looks to match exactly the string "/api"
([a-zA-Z0-9-_~ %]+) this is a capturing group: this one specifically will capture anything inside those brackets, with the + indicating to capture 1 or more, so for example, this section will match abAB25-_ %
(?:\/page\/([a-zA-Z0-9-_~ %]+)) this groups multiple tokens together as well, but does not create a capturing group like above (the ?: makes it non-captuing). You are first matching a string exactly like "/page/" followed by a group exactly like mentioned in the paragraph above (that matches a-z, A-Z, 0-9, etc.
?$ is at the end, and the ? means capture 0 or more of the precending group, and the $ matches the end of the string
This regex will match this string, for example: /api/abAB25-_ %/page/abAB25-_ %
You may be able to take advantage of capturing groups, however, and use something like this instead to get similar results: ^\/api\/([a-zA-Z0-9-_~ %]+)\/page\/\1?$. Here, we are using \1 to reference that first capturing group and match exactly the same tokens it is matching. EDIT: actually, this probably won't work, since the text after /api/ and the text after /page/ will most likely be different, carrying on...
Afterwards, you are are adding "dir" to the beginning of your search, so you can now match someting like this: dir/api/abAB25-_ %/page/abAB25-_ %
You have also now converted the regex to a string, so like Crayon Violent pointed out in their comment, this will break your expected funtionality. You can fix this by using .source on your regex: var matchedData = url.match(regVar.source); https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source
Now you can properly match a string like this: dir/api/11aa/page/2017 see this example: https://repl.it/Mj8h
As mentioned by Crayon Violent in the comments, it seems you're passing a String rather than a regular expression in the .match() function. maybe try the following:
url.match(new RegExp(regVar, "i"));
to convert the string to a regular expression. The "i" is for ignore case; don't know that's what you want. Learn more here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Send pattern to a function

I have a personal function who take an id and a pattern for check some input.
var id, schema;
function checkField(id, schema){
var input = id.val();
var pattern = schema;
if (!input.match(pattern)){
console.log('Input = '+input);
console.log('Pattern = '+pattern);
id.removeClass().addClass("error");
$(".oke").css({display: 'none'});
}else{
console.log('Classe = ok');
id.removeClass().addClass("ok");
$(".nope").css({display: 'none'});
}
}
// Vérification téléphone
$("#tel").focusout(function(){
checkField($(this), "/0[1-7,9]\d{8}/");
});
// Vérification code postale
$("#cp").focusout(function(){
checkField($(this), "/^((0[1-9])|([1-8][0-9])|(9[0-8])|(2A)|(2B))[0-9]{3}$/");
});
But the if condition always return null (!input.match(pattern)).
The two console log return the number write in input, and the pattern correctly, why the if is always false ?
When you pass "/0[1-7,9]\d{8}/" to the String#match(), the single \ before d is removed as it is an unknown escape sequence and the / around the pattern are treated as literal / symbols in the pattern. Thus, you get no matches. Also, the , in the character class is also considered a literal comma, I am sure you want to remove it from the pattern. Besides, the first pattern lacks ^ at the start and $ anchor at the end if you plan to match the entire string. Either pass "^0[1-79]\\d{8}$" or - preferred - use a regex literal /^0[1-7,9]\d{8}$/ (no double quotes around the pattern).
The second pattern can be shortened as /^(0[1-9]|[1-8]\d|9[0-8]|2[AB])\d{3}$/ - again, note the absence of the double quotes around the regex literal notation.
Also, it is advisable to replace if (!input.match(pattern)) with if (!pattern.test(input)) as regex.test(str) returns true or false while str.match(regex) will either return null or an array of match data.
So, what you can use is
if (!pattern.test(input)){
...
$("#tel").focusout(function(){
checkField($(this), /^0[1-79]\d{8}$/);
});
$("#cp").focusout(function(){
checkField($(this), /^(0[1-9]|[1-8]\d|9[0-8]|2[AB])\d{3}$/);
})
JavaScript regex patterns are not strings, you should remove the double quotes.
$("#tel").focusout(function(){
checkField($(this), /0[1-7,9]\d{8}/);
});
$("#cp").focusout(function(){
checkField($(this), /^((0[1-9])|([1-8][0-9])|(9[0-8])|(2A)|(2B))[0-9]{3}$/);
})

Need a Regex that can be applied on JavaScript

I am looking for a regular expression in js where as it can accept anything say numbers,characters,special characters etc but no two or more consecutive special characters. Tried different combinations, but could not succeed.
for example:
abcd -- valid
abcd # dfds -- valid
abcd## ssf -- invalid
hi#try$example#test - valid
hi######hello --- invalid
This regExp returns true for hi######hello, you can invert results as you like:
var regExp = /(?:.)*(?:[#$&#?]{2})+(?:.)*/g // #$&#? - your symbols go here
regExp.test("hi######hello"); // true
regExp.test("hi#try$example#test"); // false

Categories

Resources