Reputation: 858
Lets say,
let sentence= "Dear user {#val#}{#val#} thanks"
{#val#} is the dynamic value in the above sentence. Here in place of {#val#}, there can be any values but atleast 0 and maximum 5 characters can be there. So I'm substituting the {#val#} as .{0,5} . I dont need to consider spaces except for the {#val#} portion, so my formed regex would be,
let regex = /^Dear\s*user\s*.{0,5}.{0,5} thanks$/i
let customermsg = "Dear user 1 2 thanks" //Should be valid
let customermsg1 = "Dear user 12345 6789 thanks" //Should be valid
let customermsg2 = "Dear user 123 5 6789 thanks" //Should be valid because space can also be considered as a character and for fist .{0,5} => 123 5 and for second .{0,5} => 6789
let customermsg3 = "Dear user 1 thanks" //Should pass
let customermsg4 = "Dea r user 1 tha nks" // Should Pass since spaces are not considered in the static portion.
but when I try to test using below,
regex.test(customermsg)
Its quite opposite. Even I have tried the below,
let splitters=/{\\#val\\#}|((\\s\*))/gi;
sentence = sentence.replace(splitters, (x, y) => y ? y : ".(\\S{0,5})");
This returns the regex as,
/^Dear\s*user\s*.(\S{0,5}).(\S{0,5})\s*thanks$/
But this is also not working as expected. I'm stuck on this. Please help me.
Upvotes: 6
Views: 585
Reputation: 39464
Not sure if I've completely understood your requirements but if you wish to allow whitespace between any of the letters you can do something like this:
^\s*D\s*e\s*a\s*r\s*u\s*s\s*e\s*r\s*(?:.\s*){0,5}\s*(?:.\s*){0,5}\s*t\s*h\s*a\s*n\s*k\s*s\s*$
Explanation: \s*
is placed before and after every letter to allow whitespace. For the character ranges, (?:.\s*){0,5}
is used to allow whitespace after each counted character. (The ?:
at the start excludes it as a capturing group.)
Demo: https://regex101.com/r/2ZAqui/1
Upvotes: 0
Reputation: 1926
https://regex101.com/r/qBFSxq/1
This can be one way of solving it: ^Dear\s*user(\s*\d)?(?(1)(.{1,5})(?=(\s{1,}))(?<!(\s{2}))(.{1,5}) thanks|\s*thanks)$
Edit: added regex positive lookahead construct ((.{1,5})(?=(\s{1,}))
), https://www.regular-expressions.info/lookaround.html, as well as using conditionals inside regex ((\s*\d)?(?(1)...
) and negative lookbehind ((?<!(\s{2}))(.{1,5})
)
Upvotes: 1
Reputation: 163642
You could use s capture group for the part before the match, and start the match with a single non whitespace char.
Assert 1-9 chars at the right followed by thanks
. If that is the case, match at least another non whitespace char followed by the rest until you reach thanks
.
For example
let regex = /^(Dear\s*user\s*)\S(?=.{1,9} thanks$)\s*\S.*(?= thanks$)/i;
[
"Dear user 1 2 thanks",
"Dear user 12345 6789 thanks",
"Dear user 123 5 6789 thanks",
"Dear user 1 thanks",
"Dear user 1 thanks"
].forEach(s =>
console.log(s.replace(regex, (m, g1) => g1 + "{#val#}{#val#}"))
);
Or if there can be only digits and spaces with a single capture group
let regex = /^(Dear\s*user\s*)\d(?=[ \d]*\d)[ \d]{1,9}(?= thanks$)/i;
[
"Dear user 1 2 thanks",
"Dear user 12345 6789 thanks",
"Dear user 123 5 6789 thanks",
"Dear user 1 thanks",
"Dear user 1 thanks",
"Dear user 12345 64789 thanks"
].forEach(s =>
console.log(s.replace(regex, (m, g1) => g1 + "{#val#}{#val#}"))
);
Upvotes: 1
Reputation: 3863
As I understand it you want
And also
The first point is the trickiest because you need to ensure that the first value does not start with a space while the second value can, yet still be the same regex. Essentially you have two different requirements here.
The only solution I can think of is to do a lookahead to ensure that the next character after the optional spaces after user is a non-space character.
/^Dear\s*user\s*(?=\S)(.{1,5}.{1,5}) thanks$/
https://regex101.com/r/AtUxDS/2
Upvotes: 1
Reputation: 7334
What you need is to check if a number and white spaces are present multiple times according to
"Dear user 1 thanks" //Should fail since only one value is there
So, your regex is fine, except that it doesn't check if a number and white spaces are present more than one times.
Use the following regex
Dear\s*user\s*([\d]+[\s]+){2,5}\s*thanks$
([\d]+[\s]+){2,5}\s*
The ([\d]+[\s]+){2,5}\s*
part makes it sure that a number is present atleast two times, so a single number in the string Dear user ... thanks
will fail.
You can use as many white spaces before, between and after the digits as you please.
let regex = /Dear\s*user\s*([\d]+[\s]+){2,5}\s*thanks$/i
let customermsg = "Dear user 1 2 thanks" //Should be valid
let customermsg1 = "Dear user 12345 6789 thanks" //Should be valid
let customermsg2 = "Dear user 123 5 6789 thanks" //Should be valid because space can also be considered as a character and for fist .{1,5} => 123 5 and for second .{1,5} => 6789
let customermsg3 = "Dear user 1 thanks" //Should fail since only one value is there
let customermsg4 = "Dear user 435 4523 thanks" // With many spaces
console.log(regex.test(customermsg));
console.log(regex.test(customermsg1));
console.log(regex.test(customermsg2));
console.log(regex.test(customermsg3));
console.log(regex.test(customermsg4));
Upvotes: 1