How to dynamically combine two regex? [duplicate] - javascript

This question already has answers here:
Combining regular expressions in Javascript
(6 answers)
Combine Regexp?
(6 answers)
Closed 3 years ago.
Can two regex be combined? Like it should match this regex or the other. Ideally exclusively (xor).
For instance, I want to validate a phone number against a landline phone number regex and a mobile phone number regex.
I wish I could do something like this but it doesn't work:
const landlinePhoneRegExp = /(^1300\d{6}$)|(^1800|1900|1902\d{6}$)|(^0[2|3|7|8]{1}[0-9]{8}$)|(^13\d{4}$)|(^04\d{2,3}\d{6}$)/
const mobilePhoneRegExp = /^04[0-9 ]+/
const stripOutDelimiters = regex => etc...
const phoneRegExp = `/${stripOutDelimiters(landlinePhoneRegExp)}|${stripOutDelimiters(mobilePhoneRegExp)}/`,
UPDATE: I forgot to add that I'm using the Yup library for validation! The code looks like this:
const validationSchema = (t, i18n) => Yup.object.shape({
phone: Yup.string()
.required(t('formValidationPhoneRequired'))
.matches(localeRegex[i18n.language].phoneRegExp, t('formValidationPhoneInvalid'))
})
This explains why I was trying to dynamically combine the two regex into one like in the non-working example above.
I've been looking at the docs for a while now but there doesn't seem to be a way to do that. Maybe lazy() would be useful but apparently I can't use string.matches() then... unless I match (landlineMatch || mobileMatch) to boolean(), but how could I do that?
phone: Yup.lazy((value) => {
const landlineMatch = value.match(localeRegex[i18n.language].landlinePhoneRegExp)
const mobileMatch = value.match(localeRegex[i18n.language].mobilePhoneRegExp)
return Yup.string()
.required(t('formValidationPhoneRequired'))
.matches( ??? , t('formValidationPhoneInvalid'))
})

You're almost done, you just need to test if they match.
To test if a string matches, just use String.prototype.match():
landlineMatch = str.match(landlinePhoneRegExp)
mobileMatch = str.match(mobilePhoneRegExp)
There's no shortcut for the logical XOR test, you'll just have to use a combination of && and || like so:
(landlineMatch || mobileMatch) && !(landlineMatch && mobileMatch)

Related

How to validate composed strings with regex [duplicate]

This question already has answers here:
Check whether a string matches a regex in JS
(13 answers)
Closed 4 months ago.
I want to validate/write a regex of this form: uuid OR uuid-cust-uuid
It should ONLY return true when I test with a valid uuid OR a composed uuid like uuid-cust-uuid
Here is the regex I have written thus far:
const uuid =
/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}(\-cust\-[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12})?/;
You can use the test method and it will do the job.
const regexUUID = /[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}(\-cust\-[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12})?/;
const uuid = 'ec3bf3c6-85be-4169-971c-0c49be945b51';
console.log(regexUUID.test(uuid));
Edited:
As for your requirement, you can try something like this:
// Wrtie base uuid regex
const baseUUIDRegex = '[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}';
// Then use it inside another regex like this
const customRegex = `^${baseUUIDRegex}-cust-${baseUUIDRegex}$`;
console.log('ec3bf3c6-85be-4169-971c-0c49be945b51-cust-ec3bf3c6-85be-4169-971c-0c49be945b51'.match(customRegex));
Hope it will be helpful for you.

How to filter a string data? [duplicate]

This question already has answers here:
Filter array by string length in javascript [duplicate]
(3 answers)
Closed 3 years ago.
I have a string for example:-
String: Notification 'Arcosa-Incident assigned to my group' 8ff7afc6db05eb80bfc706e2ca96191f included recipients as manager of a group in the notification's "Groups" field: 'Ruchika Jain' 9efa38ba0ff1310031a1e388b1050e3f
So basically i convert it into an array using .split(' ') method to make it comma separated values, now i want to filter this array and want only values which are 32 character long and remove rest of values.
Please help me achieve this. Alternate solutions are also welcomed. Thanks in advance.
Assuming you want to grab those IDs you can simply use a regex with match on the string without splitting/filtering it. (Note: I had to escape the single quotes in the text.)
const str = 'String: Notification \'Arcosa-Incident assigned to my group\' 8ff7afc6db05eb80bfc706e2ca96191f included recipients as manager of a group in the notification\'s "Groups" field: \'Ruchika Jain\' 9efa38ba0ff1310031a1e388b1050e3f';
const matches = str.match(/[a-f0-9]{32}/g);
console.log(matches);
Like so:
var arr = ...;
var filtered = arr.filter(word => word.length === 32);
Edit: this may be a bad idea if you want to parse only the GUIDs. It could certainly be that a name like "Ruchika" is also 32 characters long. Maybe, consider using regular expressions instead.

regex to replace anything that is not a number or period in string [duplicate]

This question already has answers here:
Regex to replace everything except numbers and a decimal point
(7 answers)
Closed 3 years ago.
I am trying to write a regex that replaces anything that isn't a digit or a . in a string.
For example:
const string = 'I am a 1a.23.s12h31 dog'`
const result = string.replace(/[09.-]/g, '');
// result should be `1.23.1231`
Can anyone see what I am doing wrong here.
You could change your regex to [^0-9.]+:
const result = string.replace(/[^0-9.]+/g, "");
Alternatively, if you don't want a regex, use split and filter, then join:
const result = string.split("").filter(s => isNaN(s) || s == ".").join("");

How to create regular expression in a loop? [duplicate]

This question already has answers here:
Javascript Regex: How to put a variable inside a regular expression? [duplicate]
(9 answers)
Closed 4 years ago.
I currently have a regex that looks like:
const ignoreRegex = new RegExp(/^\/(?!fonts|static).*$/)
However, I also have a dynamic array of strings like "test" which need to be ignored too. I need to somehow map through this array and add each string to the regex, such that:
const ignoreRegex = new RegExp(/^\/(?!fonts|static + ignoreRoutes.map(x => `|${x}`) + ).*$/)
How do I do this?
You can omit the / / surrounding your regular expression and use a string in the RegExp constructor.
See the code below.
const ignoreFolders = ["fonts", "static"];
const ignoreRoutes = ["route1", "route2"];
const ignore = ignoreFolders.concat(ignoreRoutes);
const ignoreRegex = new RegExp(`^\/(?!${ignore.join("|")}).*$`);
console.log(ignoreRegex);
If you have any regex special characters in your string, they will be escaped automatically.
const ignoreRoutes = ["fonts","static","aaa","bbb","ccc"];
const ignoreRegex = new RegExp(`^\\/(?!${ignoreRoutes.join("|")}).*$`);

Looking to trim a string using javascript / regex [duplicate]

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 4 years ago.
I'm looking for some assistance with JavaScript/Regex when trying to format a string of text.
I have the following IDs:
00A1234/A12
0A1234/A12
A1234/A12
000A1234/A12
I'm looking for a way that I can trim all of these down to 1234/A12. In essence, it should find the first letter from the left, and remove it and any preceding numbers so the final format should be 0000/A00 or 0000/AA00.
Is there an efficient way this can be acheived by Javascript? I'm looking at Regex at the moment.
Instead of focussing on what you want to strip, look at what you want to get:
/\d{4}\/[A-Z]{1,2}\d{2}/
var str = 'fdfhfjkqhfjAZEA0123/A45GHJqffhdlh';
match = str.match(/\d{4}\/[A-Z]{1,2}\d{2}/);
if (match) console.log(match[0]);
You could seach for leading digits and a following letter.
var data = ['00A1234/A12', '0A1234/A12', 'A1234/A12', '000A1234/A12'],
regex = /^\d*[a-z]/gi;
data.forEach(s => console.log(s.replace(regex, '')));
Or you could use String#slice for the last 8 characters.
var data = ['00A1234/A12', '0A1234/A12', 'A1234/A12', '000A1234/A12'];
data.forEach(s => console.log(s.slice(-8)));
You could use this function. Using regex find the first letter, then make a substring starting after that index.
function getCode(s){
var firstChar = s.match('[a-zA-Z]');
return s.substr(s.indexOf(firstChar)+1)
}
getCode("00A1234/A12");
getCode("0A1234/A12");
getCode("A1234/A12");
getCode("000A1234/A12");
A regex such as this will capture all of your examples, with a numbered capture group for the bit you're interested in
[0-9]*[A-Z]([0-9]{4}/[A-Z]{1,2}[0-9]{2})
var input = ["00A1234/A12","0A1234/A12","A1234/A12","000A1234/A12"];
var re = new RegExp("[0-9]*[A-Z]([0-9]{4}/[A-Z]{1,2}[0-9]{2})");
input.forEach(function(x){
console.log(re.exec(x)[1])
});

Categories