Allow only certain character in string. Javascript - javascript

I have no idea, why this simple code is not working. I am planning to match a string against the allowed pattern.
The string should ONLY have a-z, A-Z, 0-9, _ (underscore), . (dot) , - (hiphen).
Below is code:
var profileIDPattern = /[a-zA-Z0-9_.-]./;
var str = 'Heman%t';
console.log('hemant',profileIDPattern.test(str));
The code logs 'true' for below string, although these string DOES NOT match the pattern.
'Heman%t' -> true
'#Hemant$' -> true
I dont know what is the problem.

Try changing it to this RegExp (/^[a-zA-Z0-9_.-]*$/):
var profileIDPattern = /^[a-zA-Z0-9_.-]*$/;
var str1 = 'Hemant-._67%'
var str2 = 'Hemant-._67';
console.log('hemant1',profileIDPattern.test(str1));
console.log('hemant2',profileIDPattern.test(str2));

Issues : [a-zA-Z0-9_.-] will match any character inside [] and . will match anything after so basically it will match the mention character and any other character
Use ^ and $ anchor to mention start and end of match and remove .
^[a-zA-Z0-9_.-]+ : starting with any given value inside []
[a-zA-Z0-9_.-]+$ : one or more matches and $ to end the match
var profileIDPattern = /^[a-zA-Z0-9_.-]+$/;
console.log('hemant', profileIDPattern.test('Heman%t')); // no match -
console.log('hemant-._', profileIDPattern.test('hemant-._')); // valid match
console.log('empty', profileIDPattern.test('')); // no match ,empty

Related

JavaScript Regex finding all substrings that matches with specific starting and ending pattern

I want a Javascript regex or with any possible solution,
For a given string finds all the substrings that start with a particular string and end with a particular character. The returned set of subStrings can be an Array.
this string can also have nested within parenthesis.
var str = "myfunc(1,2) and myfunc(3,4) or (myfunc(5,6) and func(7,8))";
starting char = "myfunc" ending char = ")" . here ending character should be first matching closing paranthesis.
output: function with arguments.
[myfunc(1,2),
myfunc(3,4),
myfunc(5,6),
func(7,8)]
I have tried with this. but, its returning null always.
var str = "myfunc(1,2) and myfunc(3,4) or (myfunc(5,6) and func(7,8))";
var re = /\myfunc.*?\)/ig
var match;
while ((match = re.exec(str)) != null){
console.log(match);
}
Can you help here?
I tested your regex and it seems to work fine:
let input = "myfunc(1,2) and myfunc(3,4) or (myfunc(5,6) and func(7,8))"
let pattern = /myfunc.*?\)/ig
// there is no need to use \m since it does nothing, and NO you dont need it even if you use 'm' at the beginning.
console.log(input.match(pattern))
//[ "myfunc(1,2)", "myfunc(3,4)", "myfunc(5,6)" ]
If you use (?:my|)func\(.+?\) you will be able to catch 'func(7,8)' too.
(?:my|)
( start of group
?: non capturing group
my| matches either 'my' or null, this will match either myfunc or func
) end of group
Test the regex here: https://regex101.com/r/3ujbdA/1

Extract a part of a regex name

Examples of filenames
FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
FDIP_fr-fr-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
FDIP_de-de-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
REGEX is FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
The only part I need is the translation code which is 'en-gb', 'fr-fr' , 'de-de.
How do I extract just that part of the filename?
Modified the regex little bit to match the numbers and text. You can play around here
Explanation
to capture a group you need to wrap the regex into () this will capture as a group.
to do the named capturing you can (?<name_of_group>) and then you can access by name.
Here goes the matching process.
[a-z]{2} match 2 char from a-z
[a-zA-Z0-9] match any char of a-z or A-Z or 0-9
g means global flag i.e. match all.
i means ignore case.
var r = /FDIP_([a-z]{2}-[A-Z]{2})-[a-z]{2}_Text_v1_[0-9A-Z]{8}_[A-Z0-9]{14}.txt/gi;
let t = 'FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt';
let dd = r.exec(t);
console.log(dd[1]);
This is example of group capturing
See the name in the regex and the object destructing name is matching.
const { groups: { language } } = /FDIP_(?<language>[a-z]{2}-[A-Z]{2})-[a-z]{2}_Text_v1_[0-9A-Z]{8}_[A-Z0-9]{14}.txt/gi.exec('FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt');
console.log(language);
To solve your problem, you should:
Fix your regex:
FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
// to
FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[0-9]{8}_[0-9]{14}.txt
Use get value from first group by using regex.exec function
const fileNames = [
'FDIP_en-gb-nn_Text_v1_20190101_12345678901234.txt',
'FDIP_fr-fr-nn_Text_v1_20200202_12345678901234.txt',
'FDIP_de-de-nn_Text_v1_20180808_12345678901234.txt']
const cultureNames = fileNames.map(name => {
const matched = /FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[0-9]{8}_[0-9]{14}.txt/.exec(name)
return matched && matched[1]
})
console.log(cultureNames)
Change FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
to
let pattern = /FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[\w]{8}_[\w]{14}.txt/;
var str = 'FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt';
console.log(str.match(pattern)[1]);

exec from regex returns null

This is my code snippet:
var myString = '#EXTINF:-1 group-title="|FR| CHAINES FRANÇAISES |FR|",|FR|*****CANALSAT*****|FR|';
var group_title = /(group-title=")(\S*)["]/;
var matchgroup_title = group_title.exec(myString);
console.log(matchgroup_title);
I am not familiar to regex so I can't understand this code. Why does exec here return null?
The problem exists because of \S*. If you pop it into regex101.com, you'll see:
So, \s* will match any non-whitespace character, and a space is considered a whitespace character, so this does not match. You can simply use [^"] to check for anything that isn't another quote.
You can simplify this to:
var myString = '#EXTINF:-1 group-title="|FR| CHAINES FRANÇAISES |FR|",|FR|*****CANALSAT*****|FR|';
var group_title = /group-title="([^"]+)"/;
var matchgroup_title = group_title.exec(myString);
console.log(matchgroup_title);
(group-title=") matches group-title="
(\S*) matches zero or more non-whitespace characters, so |FR|
["] then matches a ", but there isn't one (well, there is, but there are whitespace characters first, so no match).

getting values from a string using regular expression

Could anyone help me with this regular expression issue?
expr = /\(\(([^)]+)\)\)/;
input = ((111111111111))
the one I would need to be working is = ((111111111111),(222222222),(333333333333333))
That expression works fine to get 111111 from (input) , but not when there are also the groups 2222... and 3333.... the input might be variable by variable I mean could be ((111111111111)) or the one above or different (always following the same parenthesis pattern though)
Is there any reg expression to extract the values for both cases to an array?
The result I would like to come to is:
[0] = "111111"
[1] = "222222"
[2] = "333333"
Thanks
If you are trying to validate format while extracting desired parts you could use sticky y flag. This flag starts match from beginning and next match from where previous match ends. This approach needs one input string at a time.
Regex:
/^\(\(([^)]+)\)|(?!^)(?:,\(([^)]+)\)|\)$)/yg
Breakdown:
^\(\( Match beginning of input and immedietly ((
( Start of capturing group #1
[^)]+ Match anything but )
)\) End of CG #1, match ) immediately
| Or
(?!^) Next patterns shouldn't start at beginning
(?: Start of non-capturing group
,\(([^)]+)\) Match a separetd group (capture value in CG #2, same pattern as above)
| Or
\)$ Match ) and end of input
) End of group
JS code:
var str = '((111111111111),(222222222),(333333333333333))';
console.log(
str.replace(/^\(\(([^)]+)\)|(?!^)(?:,\(([^)]+)\)|\)$)/yg, '$1$2\n')
.split(/\n/).filter(Boolean)
);
You can replace brackes with , split it with , and then use substring to get the required number of string characters out of it.
input.replace(/\(/g, '').replace(/\)/g, '')
This will replace all the ( and ) and return a string like
111111111111,222222222,333333333333333
Now splitting this string with , will result into an array to what you want
var input = "((111111111111),(222222222),(333333333333333))";
var numbers = input.replace(/\(/g, '').replace(/\)/g, '')
numbers.split(",").map(o=> console.log(o.substring(0,6)))
If the level of nesting is fixed, you can just leave out the outer () from the pattern, and add the left parentheses to the [^)] group:
var expr = /\(([^()]+)\)/g;
var input = '((111111111111),(222222222),(333333333333333))';
var match = null;
while(match = expr.exec(input)) {
console.log(match[1]);
}

How to use a variable inside Regex?

I have this line in my loop:
var regex1 = new RegExp('' + myClass + '[:*].*');
var rule1 = string.match(regex1)
Where "string" is a string of class selectors, for example: .hb-border-top:before, .hb-border-left
and "myClass" is a class: .hb-border-top
As I cycle through strings, i need to match strings that have "myClass" in them, including :before and :hover but not including things like hb-border-top2.
My idea for this regex is to match hb-border-top and then :* to match none or more colons and then the rest of the string.
I need to match:
.hb-fill-top::before
.hb-fill-top:hover::before
.hb-fill-top
.hb-fill-top:hover
but the above returns only:
.hb-fill-top::before
.hb-fill-top:hover::before
.hb-fill-top:hover
and doesn't return .hb-fill-top itself.
So, it has to match .hb-fill-top itself and then anything that follows as long as it starts with :
EDIT:
Picture below: my strings are the contents of {selectorText}.
A string is either a single class or a class with a pseudo element, or a rule with few clases in it, divided by commas.
each string that contains .hb-fill-top ONLY or .hb-fill-top: + something (hover, after, etc) has to be selected. Class is gonna be in variable "myClass" hence my issue as I can't be too precise.
I understand you want to get any CSS selector name that contains the value anywhere inside and has EITHER : and 0+ chars up to the end of string OR finish right there.
Then, to get matches for the .hb-fill-top value you need a solution like
/\.hb-fill-top(?::.*)?$/
and the following JS code to make it all work:
var key = ".hb-fill-top";
var rx = RegExp(key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "(?::.*)?$");
var ss = ["something.hb-fill-top::before","something2.hb-fill-top:hover::before","something3.hb-fill-top",".hb-fill-top:hover",".hb-fill-top2:hover",".hb-fill-top-2:hover",".hb-fill-top-bg-br"];
var res = ss.filter(x => rx.test(x));
console.log(res);
Note that .replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') code is necessary to escape the . that is a special regex metacharacter that matches any char but a line break char. See Is there a RegExp.escape function in Javascript?.
The ^ matches the start of a string.
(?::.*)?$ will match:
(?::.*)?$ - an optional (due to the last ? quantifier that matches 1 or 0 occurrences of the quantified subpattern) sequence ((?:...)? is a non-capturing group) of a
: - a colon
.* - any 0+ chars other than line break chars
$ - end of the string.
var regex1 = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`)
var passes = [
'.hb-fill-top::before',
'.hb-fill-top:hover::before',
'.hb-fill-top',
'.hb-fill-top:hover',
'.hb-fill-top::before',
'.hb-fill-top:hover::before',
'.hb-fill-top:hover'
];
var fails = ['.hb-fill-top-bg-br'];
var myClass = '.hb-fill-top';
var regex = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`);
passes.forEach(p => console.log(regex.test(p)));
console.log('---');
fails.forEach(f => console.log(regex.test(f)));
var regex1 = new RegExp('\\' + myClass + '(?::[^\s]*)?');
var rule1 = string.match(regex1)
This regex select my class, and everething after if it start with : and stop when it meets a whitespace character.
See the regex in action.
Notice also that I added '\\' at the beginning. This is in order to escape the dot in your className. Otherwise it would have matched something else like
ahb-fill-top
.some-other-hb-fill-top
Also be careful about .* it may match something else after (I don't know your set of strings). You might want to be more precise with :{1,2}[\w-()]+ in the last group. So:
var regex1 = new RegExp('\\' + myClass + '(?::{1,2}[\w-()]+)?');

Categories