I am trying to validate aws arn for a connect instance but I am stuck on creating the correct regex.
Below is the string that I want to validate.
arn:aws:connect:us-west-2:123456789011:instance/0533yu22-d4cb-410a-81da-6c9hjhjucec4b9
I want to create a regex which checks below things.
arn:aws:connect:<region_name>:<12 digit account id>:instance/<an alphanumeric instance id>
Can someone please help.
Tried below
^arn:aws:connect:\S+:\d+:instance\/\S+\/queue\/\S+$
There is no /queue/ substring in your example string, and \S+ matches any no whitespace character and will cause backtracking to match the rest of the pattern.
You might update your pattern to ^arn:aws:connect:\S+:\d+:instance\/\S+$ but that will be less precise according to the things you want to check.
A bit more precise pattern could be:
^arn:aws:connect:\w+(?:-\w+)+:\d{12}:instance\/[A-Za-z0-9]+(?:-[A-Za-z0-9]+)+$
^ Start of string
arn:aws:connect: Match literally
\w+(?:-\w+)+: Match 1+ word characters and repeat matching - and 1+ word characters and then match :
\d{12}: Match 12 digits and :
instance\/ Match instance/
[A-Za-z0-9]+(?:-[A-Za-z0-9]+)+ Match 1+ alpha numerics and repeat 1+ times - and 1+ alpha numerics
$ End of string
Regex demo
You need some capture groups to facilitate this. Here I've also used named capture groups for ease of understanding.
const string = "arn:aws:connect:us-west-2:123456789011:instance/0533yu22-d4cb-410a-81da-6c9hjhjucec4b9";
// Regex broken down into parts
const parts = [
'arn:aws:connect:',
'(?<region_name>[^:]+?)', // group 1
':',
'(?<account_id>\\d{12})', // group 2
':instance\\/',
'(?<instance_id>[A-z0-9\\-]+?)', // group 3
'$'
];
// Joined parts into regex expression
const regex = new RegExp(parts.join(''));
// Execute query and assign group values to variables
const { region_name, account_id, instance_id } = regex.exec(string).groups;
console.log("region_name:", region_name);
console.log("account_id:", account_id);
console.log("instance_id:", instance_id);
Related
So, there is a task to match emails in an input agains some certain conditions. Most of them are fulfilled. All of them, actually, except one.
So, user emails have to be up to 30 characters long, but they cannot be shorter than 6 only for gmail users (the part before the #). Other types of email can have even shorter emails.
Please help me find a correct regexp!
My current one is:
^((?!.*?\.\.)[a-zA-Z0-9\.]{1,30})\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})$
Using a case insensitive match, you could write the pattern as:
^(?!.*?\.\.)(?:[a-zA-Z0-9.]{1,30}#(?!gmail\.com$)(?:[a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,4}|[a-zA-Z0-9.]{6,30}#gmail\.com)$
The pattern matches:
^ Start of string
(?!.*?\.\.) Assert not .. to the right
(?: Non capture group for the 2 alternatives
[a-z0-9.]{1,30} Match 1-30 chars specified in the character class
#(?!gmail\.com$) Match # and assert not followed by gmail.com
(?:[a-z0-9-]+\.)+[a-z0-9]{2,4} Match 1+ repetitions of the character class and . and match 2-4 chars of the second character class
| Or
[a-zA-Z0-9.]{6,30}#gmail\.com
) Close non capture group
$ End of string
Regex demo
const regex = /^(?!.*?\.\.)(?:[a-zA-Z0-9.]{1,30}#(?!gmail\.com$)(?:[a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,4}|[a-zA-Z0-9.]{6,30}#gmail\.com)$/i;
[
"testing#test.com",
"t#gmail.com",
"t#test.com",
"testing#gmail.com"
].forEach(s => console.log(`${s} --> ${regex.test(s)}`));
A bit shorter way to write it could be asserting not 1-5 characters before gmail.com:
^(?!.*?\.\.)(?![a-z0-9.]{1,5}#(?=gmail\.com$))[a-z0-9.]+#(?:[a-z0-9-]+\.)+[a-zA-Z0-9]{2,4}$
Regex demo
my collegue and I try to build a Regex (Javascript) to validate an input field for a specific format.
The field should be a comma seperated list of port declarations and could look like this:
TCP/53,UDP/53,TCP/10-20,UDP/20-30
We tried this regex:
/^[TCP/\d+,|UDP/\d+,|TCP/\d+\-\d+,|UDP/\d+\-\d+,]*[TCP/\d+|UDP/\d+|TCP/\d+\-\d+|UDP/\d+\-\d+]$/g
the regex matches, but also matches other strings as well, like this one:
TCP/53UDP53,TCP/10-20UDP20-30
Thanks for any guidance!
You don't need all those alternations, and the [ ] are not used for grouping like that. You can also make the - and digits part optional using grouping (?:...)?
To match that string format:
^(?:TCP|UDP)\/\d+(?:-\d+)?(?:,(?:TCP|UDP)\/\d+(?:-\d+)?)*$
The pattern matches:
^ Start of string
(?:TCP|UDP) Match one of the alternatives
\/\d+(?:-\d+)? Match / 1+ digits and optionally - and 1+ digits
(?: Non capture group to repeat as a whole part
,(?:TCP|UDP)\/\d+(?:-\d+)? Match a , and repeat the same pattern
)* Close non capture group and optionally repeat (If there should be at least 1 comma, change the * to +)
$ End of string
Regex demo
Alternative: split up the string, use Array.filter and a relative simple RegExp for testing.
const valid = `TCP/53,UDP/53,TCP/10-20,UDP/20-30`;
const invalid = `TCP/53UDP53,TCP/10-20UDP20-30`;
console.log(`${valid} ok? ${checkInp(valid)}`);
console.log(`${invalid} ok? ${checkInp(invalid)}`);
function checkInp(str) {
return str.split(`,`)
.filter(v => /^(TCP|UDP)\/\d+(?:-\d+)*$/.test(v))
.join(`,`)
.length === str.length;
}
I have a URL as follow:
https://res.cloudinary.com/frivillighet-norge/image/upload/v1501681528/5648f10ae4b09f27e34dd22a.jpg
and I want to match only the id of the picture at the end of the string without including .jpg. So far, I have written something like that: ^[A-Za-z0-9]{24}$ which matches a string of numbers and letters with a length of 24, since my id in the string has always length 24, but this does not work as it matches strings of length 24 only.
Any help would be appreciated.
[A-Za-z0-9]{24}(?=(\.jpg))
"(?=(.jpg))" is a lookaround. It ends the match with .jpg but does not include it.
You could make the pattern a bit more specific by matching the protocol followed by matching 1+ occurrences of a non whitespace char \S+.
Then match the last occurrence of / and capture the id which consists of 24 characters ([A-Za-z0-9]{24}) followed by matching a dot and 2 or more times a char a-z \.[a-z]{2,}
If you want to match the whole string, you could add anchors to assert the start ^ and end $ of the string.
The id is in capture group 1.
^https?:\/\/\S+\/([A-Za-z0-9]{24})\.[a-z]{2,}$
Regex demo
const regex = /https?:\/\/\S+\/([A-Za-z0-9]{24})\.\w+$/;
const str = `https://res.cloudinary.com/frivillighet-norge/image/upload/v1501681528/5648f10ae4b09f27e34dd22a.jpg`;
console.log(str.match(regex)[1])
I'm trying to create a regex using javascript that will allow names like abc-def but will not allow abc-
(hyphen is also the only nonalpha character allowed)
The name has to be a minimum of 2 characters. I started with
^[a-zA-Z-]{2,}$, but it's not good enough so I'm trying something like this
^([A-Za-z]{2,})+(-[A-Za-z]+)*$.
It can have more than one - in a name but it should never start or finish with -.
It's allowing names like xx-x but not names like x-x. I'd like to achieve that x-x is also accepted but not x-.
Thanks!
Option 1
This option matches strings that begin and end with a letter and ensures two - are not consecutive so a string like a--a is invalid. To allow this case, see the Option 2.
^[a-z]+(?:-?[a-z]+)+$
^ Assert position at the start of the line
[a-z]+ Match any lowercase ASCII letter one or more times (with i flag this also matches uppercase variants)
(?:-?[a-z]+)+ Match the following one or more times
-? Optionally match -
[a-z]+ Match any ASCII letter (with i flag)
$ Assert position at the end of the line
var a = [
"aa","a-a","a-a-a","aa-aa-aa","aa-a", // valid
"aa-a-","a","a-","-a","a--a" // invalid
]
var r = /^[a-z]+(?:-?[a-z]+)+$/i
a.forEach(function(s) {
console.log(`${s}: ${r.test(s)}`)
})
Option 2
If you want to match strings like a--a then you can instead use the following regex:
^[a-z]+[a-z-]*[a-z]+$
var a = [
"aa","a-a","a-a-a","aa-aa-aa","aa-a","a--a", // valid
"aa-a-","a","a-","-a" // invalid
]
var r = /^[a-z]+[a-z-]*[a-z]+$/i
a.forEach(function(s) {
console.log(`${s}: ${r.test(s)}`)
})
You can use a negative lookahead:
/(?!.*-$)^[a-z][a-z-]+$/i
Regex101 Example
Breakdown:
// Negative lookahead so that it can't end with a -
(?!.*-$)
// The actual string must begin with a letter a-z
[a-z]
// Any following strings can be a-z or -, there must be at least 1 of these
[a-z-]+
let regex = /(?!.*-$)^[a-z][a-z-]+$/i;
let test = [
'xx-x',
'x-x',
'x-x-x',
'x-',
'x-x-x-',
'-x',
'x'
];
test.forEach(string => {
console.log(string, ':', regex.test(string));
});
The problem is that the first assertion accepts 2 or more [A-Za-z]. You will need to modify it to accept one or more character:
^[A-Za-z]+((-[A-Za-z]{1,})+)?$
Edit: solved some commented issues
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('xggg-dfe'); // Logs true
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('x-d'); // Logs true
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('xggg-'); // Logs false
Edit 2: Edited to accept characters only
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('abc'); // Logs true
Use this if you want to accept such as A---A as well :
^(?!-|.*-$)[A-Za-z-]{2,}$
https://regex101.com/r/4UYd9l/4/
If you don't want to accept such as A---A do this:
^(?!-|.*[-]{2,}.*|.*-$)[A-Za-z-]{2,}$
https://regex101.com/r/qH4Q0q/4/
So both will accept only word starting from two characters of the pattern [A-Za-z-] and not start or end (?!-|.*-$) (negative lookahead) with - .
Try this /([a-zA-Z]{1,}-[a-zA-Z]{1,})/g
I suggest the following :
^[a-zA-Z][a-zA-Z-]*[a-zA-Z]$
It validates :
that the matched string is at least composed of two characters (the first and last character classes are matched exactly once)
that the first and the last characters aren't dashes (the first and last character classes do not include -)
that the string can contain dashes and be greater than 2 characters (the second character class includes dashes and will consume as much characters as needed, dashes included).
Try it online.
^(?=[A-Za-z](?:-|[A-Za-z]))(?:(?:-|^)[A-Za-z]+)+$
Asserts that
the first character is a-z
the second is a-z or hyphen
If this matches
looks for groups of one or more letters prefixed by a hyphen or start of string, all the way to end of string.
You can also use the I switch to make it case insensitive.
I would like to test if user type only alphanumeric value or one "-".
hello-world -> Match
hello-first-world -> match
this-is-my-super-world -> match
hello--world -> NO MATCH
hello-world-------this-is -> NO MATCH
-hello-world -> NO MATCH (leading dash)
hello-world- -> NO MATCH (trailing dash)
Here is what I have so far, but I dont know how to implement the "-" sign to test it if it is only once without repeating.
var regExp = /^[A-Za-z0-9-]+$/;
Try this:
/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/
This will only match sequences of one or more sequences of alphanumeric characters separated by a single -. If you do not want to allow single words (e.g. just hello), replace the * multiplier with + to allow only one or more repetitions of the last group.
Here you go (this works).
var regExp = /^[A-Za-z0-9]+([-]{1}[A-Za-z0-9]+)+$/;
letters and numbers greedy, single dash, repeat this combination, end with letters and numbers.
(^-)|-{2,}|[^a-zA-Z-]|(-$) looks for invalid characters, so zero matches to that pattern would satisfy your requirement.
I'm not entirely sure if this works because I haven't done regex in awhile, but it sounds like you need the following:
/^[A-Za-z0-9]+(-[A-Za-z0-9]+)+$/
You're requirement is split up in the following:
One or more alphanumeric characters to start (that way you ALWAYS have an alphanumeric starting.
The second half entails a "-" followed by one or more alphanumeric characters (but this is optional, so the entire thing is required 0 or more times). That way you'll have 0 or more instances of the dash followed by 1+ alphanumeric.
I'm just not sure if I did the regex properly to follow that format.
The expression can be simplified to: /^[^\W_]+(?:-[^\W_]+)+$/
Explanation:
^ match the start of string
[^\W_]+ match one or more word(a-zA-Z0-9) chars
(?:-[^\W_]+)+ match one or more group of '-' follwed by word chars
$ match the end of string
Test: https://regex101.com/r/MODQxw/1