How to limit a string length - javascript

I have the following regex:
^[a-zA-Z_][\-_a-zA-Z0-9]*
I need to limit it's length to 39 characters. I tried the following but it didn't work:
^[a-zA-Z_][\-_a-zA-Z0-9]*{,38}

You just need to use a limited quantifier {0,38} and an end of string anchor $:
^[a-zA-Z_][-_a-zA-Z0-9]{0,38}$
^^^^^ ^
The syntax for the limited quantifiers is {min,max} where the max parameter is optional, but the minimum should be present. Without $ you may match 39 first characters in a much longer string.
You do not have to escape a hyphen when it is placed at the beginning of a character class (thus, I suggest removing it).
Also, you can further shorten the regex with an /imodifier:
/^[a-z_][-_a-z0-9]{0,38}$/i
or even
/^[a-z_][-\w]{0,38}$/i
Regarding the question from the comment:
wouldn't also that version work (^[a-zA-Z_][-_a-zA-Z0-9]){0,39}$ with 39 characters limit?
The regex matches
(^[a-zA-Z_][-_a-zA-Z0-9]){0,39} - 0 to 39 sequences of...
^ - start of the string
[a-zA-Z_] - a single character from the specified range
[-_a-zA-Z0-9] - a single character from the specified range
$ - end of string
So, you require a match to include sequences from the start of the string. Note a start of string can be matched only once. As you let the number of such sequences to be 0, you only match either the location at the end of the string or a 2 character string like A-.
Let's see what the regex does with the Word input. It mathces the start of string with ^, then W with [a-zA-Z_], then o with [-_a-zA-Z0-9]. Then the group ends, and that equals to matching the group once. Since we can match more sequences, the regex tries to match r with ^. It fails. So, the next position is retried and failed the same way, because d is not the ^ (start of string). And that way the end of string is matched because there is a 0 occurrences of ^[a-zA-Z_][-_a-zA-Z0-9] and there is an end of string $.
See regex demo

try
^[a-zA-Z_][\-_a-zA-Z0-9]{0,38}$
[0,38] means that number of instances of characters matching [\-_a-zA-Z0-9] could be 0 to 38.

I'm adding this in case you're limiting input field entry.
While not regex, I use this function and it works well (I will add that it's important to let the user know you're limiting the input length from UI/UX point of view):
limitLength: function(element, lengthOf){
var fieldLength = element.value.length;
if(fieldLength <= lengthOf){
return true;
} else {
var str = element.value;
str = str.substring(0, str.length - 1);
element.value = str;
}
}
Usage:
<input type="text" onInput="my.namespace.limitLength(this,39)">

Related

How to replace all instance of string '&user_story=x' using regex in javascript?

I have string like this -
var string = 'callback&user_story=1&user_story=2&user_story=100&user_story=a&user_story=john';
&user_story=x (Here x can be anything) can repeat n number of times.
How to replace this '&user_story=x' with a blank value.
What would be regex for it in JS?
The regex looks like this:
var string = 'callback&user_story=1&user_story=2&user_story=100&user_story=a&user_story=john';
var re = /&user_story=.*?(?=&|$)/g
console.log(string.replace(re, ""));
Broken down:
/&user_story=.*?(?=&|$)/g
&user_story= - checks whether the match starts with "&user_story="
.*? - matches any number of any characters, but the ? makes it non-greedy, so it will find as few of these characters before finding the next part of the regex
(?=&|$) - the brackets make this a group, and ?= means it's a lookahead, i.e. it won't actually add matches to the regex match, but just checks to see they're there. It will match either another &, or the end of the string (symbolised by $).
g - is a flag which tells the regex to check the entire string, and not stop after just finding one match.

JavaScript validation of string using regular expression

I have to validate string field which start with A-za-z and can contain 0-9_. I have to set limit min 1 char and max 10 char.
Exp=/^([a-zA-Z]) +([0-9._]*)/;
Try this regex:
/^[a-zA-Z][0-9_]{0,9}$/
See demo on regex101.com.
I have to validate string field which start with A-za-z and can contain 0-9_.
I guess A-za-z is a typo, you meant A-Za-z. That is easy, we use ^ for the string start and [A-Za-z] character class for the letter.
I have to set limit min 1 char and max 10 char.
That means, we already have the "min 1 char" requirement fulfilled at Step 1 (one letter at the start). Now, we may have letters, digits, or an underscore, 0 to 9 occurrences - that is, we need to use {0,9} limiting quantifier - up to the end of string (that is, $). A shorthand pattern in JS regex for letters, digits, and underscore is \w.
Use
/^[a-zA-Z]\w{0,9}$/
var re = /^[a-zA-Z]\w{0,9}$/;
var str = 'a123456789';
if (re.test(str)) {
console.log("VALID!")
} else {
console.log("INVALID!")
}
function isValid(string){
if (string.length < 1 || string.length > 10)
return false;
return /^[a-zA-Z][0-9_]*$/.test(string);
}
console.assert(isValid("A"));
console.assert(isValid("a12345"));
console.assert(!isValid(""));
console.assert(!isValid("x123456787212134567"));
console.assert(!isValid("abcdef"));
console.assert(!isValid("012345"));
Don't try to check string length with regex, in most of the cases it is slow and burdensome.

regular expression, not reading entire string

I have a standard expression that is not working correctly.
This expression is supposed to catch if a string has invalid characters anywhere in the string. It works perfect on RegExr.com but not in my tests.
The exp is: /[a-zA-Z0-9'.\-]/g
It is failing on : ####
but passing with : aa####
It should fail both times, what am I doing wrong?
Also, /^[a-zA-Z0-9'.\-]$/g matches nothing...
//All Boxs
$('input[type="text"]').each(function () {
var text = $(this).prop("value")
var textTest = /[a-zA-Z0-9'.\-]/g.test(text)
if (!textTest && text != "") {
allFieldsValid = false
$(this).css("background-color", "rgba(224, 0, 0, 0.29)")
alert("Invalid characters found in " + text + " \n\n Valid characters are:\n A-Z a-z 0-9 ' . -")
}
else {
$(this).css("background-color", "#FFFFFF")
$(this).prop("value", text)
}
});
edit:added code
UPDATE AFTER QUESTION RE-TAGGING
You need to use
var textTest = /^[a-zA-Z0-9'.-]+$/.test(text)
^^
Note the absence of /g modifier and the + quantifier. There are known issues when you use /g global modifier within a regex used in RegExp#test() function.
You may shorten it a bit with the help of the /i case insensitive modifier:
var textTest = /^[A-Z0-9'.-]+$/i.test(text)
Also, as I mention below, you do not have to escape the - at the end of the character class [...], but it is advisable to keep escaped if the pattern will be modified later by less regex-savvy developers.
ORIGINAL C#-RELATED DETAILS
Ok, say, you are using Regex.IsMatch(str, #"[a-zA-Z0-9'.-]"). The Regex.IsMatch searches for partial matches inside a string. So, if the input string contains an ASCII letter, digit, ', . or -, this will pass. Thus, it is logical that aa#### passes this test, and #### does not.
If you use the second one as Regex.IsMatch(str, #"^[a-zA-Z0-9'.-]$"), only 1 character strings (with an optional newline at the end) would get matched as ^ matches at the start of the string, [a-zA-Z0-9'.-] matches 1 character from the specified ranges/sets, and $ matches the end of the string (or right before the final newline).
So, you need a quantifier (+ to match 1 or more, or * to match zero or more occurrences) and the anchors \A and \z:
Regex.IsMatch(str, #"\A[a-zA-Z0-9'.-]+\z")
^^ ^^^
\A matches the start of string (always) and \z matches the very end of the string in .NET. The [a-zA-Z0-9'.-]+ will match 1+ characters that are either ASCII letters, digits, ', . or -.
Note that - at the end of the character class does not have to be escaped (but you may keep the \- if some other developers will have to modify the pattern later).
And please be careful where you test your regexps. Regexr only supports JavaScript regex syntax. To test .NET regexps, use RegexStorm.net or RegexHero.
/^[a-zA-Z0-9'.-]+$/g
In the second case your (/[a-zA-Z0-9'.-]/g) was working because it matched on the first letter, so to make it correct you need to match the whole string (use ^ and $) and also allow more letters by adding a + or * (if you allow empty string).
Try this regex it matches any char which isn't part of the allowed charset
/[^a-zA-Z0-9'.\-]+/g
Test
>>regex = /[^a-zA-Z0-9'.\-]+/g
/[^a-zA-Z0-9'.\-]+/g
>>regex.test( "####dsfdfjsakldfj")
true
>>regex.test( "dsfdfjsakldfj")
false

Why does't regex match all numbers instead of numbers just at the end of the string?

I was just looking for a regex that would watch the last numerical (\d or [0-9]) in a given string , strings like:
var str = "7-Dec-1985"
var str = "#scrollto-section-4"
Of-course I found an answer in the following thread on SO HERE
I am using a regex like the following:
str.match(/\d+$/)
Works fine, no issues, now I used the following tool to analysis the regex HERE,
\d+ //matches greedy 0 to as many
$ - specifies that the search should start at the end of the string
But why does that above regex in the below example:
var str = "7-Dec-1985"
Match only 1985 why not 71985 ?
Because $ means "end of input" (or "end of line or end of input" if you specify the m flag), and \d+ means a contiguous series of digits (not digits mixed with other things). So \d+$ means "a contiguous series of digits right before the end."
If you want to match anywhere, remove the $. Additionally, if you want to match more than once, you'll need a g ("global") flag on it.
Examples -- your original:
var str = "7-Dec-1985";
document.body.innerHTML = JSON.stringify(str.match(/\d+$/));
Without the $, but no g:
var str = "7-Dec-1985";
document.body.innerHTML = JSON.stringify(str.match(/\d+/));
Without the $ and with g:
var str = "7-Dec-1985";
document.body.innerHTML = JSON.stringify(str.match(/\d+/g));
Sorry, but $ doesn't means start search at end of string.
Your regex \d+$ means match the number at end of string.
To match any number use \d+ like this.
Because there is -Dec- between 7 and 1985 which isn't digit. Also $ means end of line. So Your pattern just matches that number which is end of string (continuously).

RegExp issues - character limit and whitespace ignoring

I need to validate a string that can have any number of characters, a comma, and then 2 characters. I'm having some issues. Here's what I have:
var str="ab,cdf";
var patt1=new RegExp("[A-z]{2,}[,][A-z]{2}");
if(patt1.test(str)) {
alert("true");
}
else {
alert("false");
}
I would expect this to return false, as I have the {2} limit on characters after the comma and this string has three characters. When I run the fiddle, though, it returns true. My (admittedly limited) understanding of RegExp indicates that {2,} is at least 2, and {2} is exactly two, so I'm not sure why three characters after the comma are still returning true.
I also need to be able to ignore a possible whitespace between the comma and the remaining two characters. (In other words, I want it to return true if they have 2+ characters before the comma and two after it - the two after it not including any whitespace that the user may have entered.)
So all of these should return true:
var str = "ab, cd";
var str = "abc, cd";
var str = "ab,cd";
var str = "abc,dc";
I've tried adding the \S indicator after the comma like this:
var patt1=new RegExp("[A-z]{2,}[,]\S[A-z]{2}");
But then the string returns false all the time, even when I have it set to ab, cd, which should return true.
What am I missing?
{2,} is at least 2, and {2} is exactly two, so I'm not sure why three characters after the comma are still returning true.
That's correct. What you forgot is to anchor your expression to string start and end - otherwise it returns true when it occurs somewhere in the string.
not including any whitespace: I've tried adding the \S indicator after the comma
That's the exact opposite. \s matches whitespace characters, \S matches all non-whitespace characters. Also, you probably want some optional repetition of the whitespace, instead of requiring exact one.
[A-z]
Notice that this character range also includes the characters between Z and a, namely []^_`. You will probably want [A-Za-z] instead, or use [a-z] and make your regex case-insensitive.
Combined, this is what your regex should look like (using a regular expression literal instead of the RegExp constructor with a string literal):
var patt1 = /^[a-z]{2,},\s*[a-z]{2}$/i;
You are missing ^,$.Also the range should be [a-zA-Z] not [A-z]
Your regex should be
^[a-zA-Z]{2,}[,]\s*[A-Za-z]{2}$
^ would match string from the beginning...
$ would match string till end.
Without $,^ it would match anywhere in between the string
\s* would match 0 to many space..

Categories

Resources