Regex detect chars duplicates - javascript

I use expression to detect duplicate one char in string.
if (str.replace(/[^#]/g, '').length > 1) {...}
Now, i wish detect duplicate more than one char.
For sample, lets try detect duplicates of # or #:
Wordwithone#here - match
Word#withduplicate#here - not
Word#withoneandone#here - match
Is it possible with regexp detect duplicate char from set of chars? (## as in sample)

Your attempt in the comment /([#])\1{2,}/ig will search for consecutive # in the string.
It only needs a simple modification to make it work:
/([##])[\s\S]*?\1/.test(inputString)
Either [\s\S]*? or [\s\S]* would work, just that the order of searching would be a bit different:
*? is lazy, so the search for duplicate will start from the adjacent character.
* is greedy, so the search will start from the last character in the string.
The point is to allow any number of characters to come in-between the 2 duplicates [\s\S]*. I used [\s\S] to allow any character, as opposed to . which excludes the following new line characters: \n, \r, \u2028 and \u2029.

Related

RegExp avoid double space and space before characters

I'm trying to write a regular expression in order to not allow double spaces anywhere in a string, and also force a single space before a MO or GO mandatory, with no space allowed at the beginning and at the end of the string.
Example 1 : It is 40 GO right
Example 2 : It is 40GO wrong
Example 3 : It is 40 GO wrong
Here's what I've done so far ^[^ ][a-zA-Z0-9 ,()]*[^;'][^ ]$, which prevents spaces at the beginning and at the end, and also the ";" character. This one works like a charm.
My issue is not allowing double spaces anywhere in the string, and also forcing spaces right before MO or GO characters.
After a few hours of research, I've tried these (starting from the previous RegExp I wrote):
To prevent the double spaces: ^[^ ][a-zA-Z0-9 ,()]*((?!.* {2}).+)[^;'][^ ]$
To force a single space before MO: ^[^ ][a-zA-Z0-9 ,()]*(?=\sMO)*[^;'][^ ]$
But neither of the last two actually work. I'd be thankful to anyone that helps me figure this out
The lookahead (?!.* {2} can be omitted, and instead start the match with a non whitespace character and end the match with a non whitespace character and use a single space in an optionally repeated group.
If the string can not contain a ' or ; then using [^;'][^ ]$ means that the second last character should not be any of those characters.
But you can omit that part, as the character class [a-zA-Z0-9,()] does not match ; and '
Note that using a character class like [^ ] and [^;'] actually expect a single character, making the pattern that you tried having a minimum length.
Instead, you can rule out the presence of GO or MO preceded by a non whitespace character.
^(?!.*\S[MG]O\b)[a-zA-Z0-9,()]+(?: [a-zA-Z0-9,()]+)*$
The pattern matches:
^ Start of string
(?!.*\S[MG]O\b) Negative lookahead, assert not a non whitspace character followed by either MO or GO to the right. The word boundary \b prevents a partial word match
[a-zA-Z0-9,()]+ Start the match with 1+ occurrences of any of the listed characters (Note that there is no space in it)
(?: [a-zA-Z0-9,()]+)* Optionally repeat the same character class with a leading space
$ End of string
Regex demo

Create a regex to extract a string that contain a noral character and escaped string without DOS

I have a string like this:
///////AB?\a\b\c\d\d\e\\f\a\a\b\cd\ed\fmnopqrstuvwxy\z\a\a\a\a\a\a\a\a\a///imgy
it started with /// and ended with ///imgy (i and/or m and/or g and/or y), and between the beginning and end are the character are normal character like a or escaped character like \a.
Here is my regex:
/^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/
But the problem is that it is reported as "vulnerable to denial-of-service attacks". The main part that has the problem is
(?:\\?[\s\S])+
How can I create a right one that can figure out both a and \a? Thank you!
Regex Demo
Update:
I just found to use the following regex:
(?:\\[\s\S]+?)|(?:(?<!\\)[\s\S]+?)|(?:(?<=\\\\)[\s\S]+?)
to replace the old problematic part (?:\\?[\s\S])+?, and in this way, it can avoid requires exponential time to match certain inputs, and avoid vulnerable to denial-of-service attacks.
The details:
(?:\\[\s\S]+?) match any \a
(?:(?<!\\)[\s\S]+?) match any a, but not following \.
(?:(?<=\\\\)[\s\S]+?) match any a, but much following \\. This to make sure f is matched that following \\.
So the whole regex will look like this:
^\/{3}((?:\\[\s\S]+?)|(?:(?<!\\)[\s\S]+?)|(?:(?<=\\\\)[\s\S]+?))\/{3}([imgy]{0,4})(?!\w)
You might list the characters that are allowed to a character class, and optionally repeat an escaped character [a-z]
^\/{3,}[A-Za-z?]+(?:\\[a-z\\][A-Za-z?]*)*\/\/\/[imgy]{0,4}$
The pattern matches:
^ Start of string
\/{3,}[A-Za-z?]+ Match 3 or more / and 1 or more times any of the listed allowed chars
(?: Non capture group
\\[a-z\\] Match an escaped char a-z or \\
[A-Za-z?]* Optionally match any of the listed
)* Close an optionally repeat the group
\/\/\/[imgy]{0,4} Match /// and 0-4 times any of i m g or y If there should be at least a single char, you can use {1,4}
$ End of string
Regex demo

Regex: how to exclude empty match from somthing like (RegexA)?(RegexB)?(RegexA)? [duplicate]

I have regex which works fine in my application, but it matches an empty string too, i.e. no error occurs when the input is empty. How do I modify this regex so that it will not match an empty string ? Note that I DON'T want to change any other functionality of this regex.
This is the regex which I'm using: ^([0-9\(\)\/\+ \-]*)$
I don't know a lot about regex formulation myself, which is why I'm asking. I have searched for an answer, but couldn't find a direct one. Closest I got to was this: regular expression for anything but an empty string in c#, but that doesn't really work for me ..
Replace "*" with "+", as "*" means "0 or more occurrences", while "+" means "at least one occurrence"
There are a lot of pattern types that can match empty strings. The OP regex belongs to an ^.*$ type, and it is easy to modify it to prevent empty string matching by replacing * (= {0,}) quantifier (meaning zero or more) with the + (= {1,}) quantifier (meaning one or more), as has already been mentioned in the posts here.
There are other pattern types matching empty strings, and it is not always obvious how to prevent them from matching empty strings.
Here are a few of those patterns with solutions:
[^"\\]*(?:\\.[^"\\]*)* ⇒ (?:[^"\\]|\\.)+
abc||def ⇒ abc|def (remove the extra | alternation operator)
^a*$ ⇒ ^a+$ (+ matches 1 or more chars)
^(a)?(b)?(c)?$ ⇒ ^(?!$)(a)?(b)?(c?)$ (the (?!$) negative lookahead fails the match if end of string is at the start of the string)
or ⇒ ^(?=.)(a)?(b)?(c?)$ (the (?=.) positive lookahead requires at least a single char, . may match or not line break chars depending on modifiers/regex flavor)
^$|^abc$ ⇒ ^abc$ (remove the ^$ alternative that enables a regex to match an empty string)
^(?:abc|def)?$ ⇒ ^(?:abc|def)$ (remove the ? quantifier that made the (?:abc|def) group optional)
To make \b(?:north|south)?(?:east|west)?\b (that matches north, south, east, west, northeast, northwest, southeast, southwest), the word boundaries must be precised: make the initial word boundary only match start of words by adding (?<!\w) after it, and let the trailing word boundary only match at the end of words by adding (?!\w) after it.
\b(?:north|south)?(?:east|west)?\b ⇒ \b(?<!\w)(?:north|south)?(?:east|west)?\b(?!\w)
You can either use + or the {min, max} Syntax:
^[0-9\(\)\/\+ \-]{1,}$
or
^[0-9\(\)\/\+ \-]+$
By the way: this is a great source for learning regular expressions (and it's fun): http://regexone.com/
Obviously you need to replace Replace * with +, as + matches 1 or more character. However inside character class you don't to do all that escaping you're doing. Your regex can be simplified to:
^([0-9()\/+ -]+)$

Find single backslashes followed by alphabet

I need to a regres that find all single backslashes followed by an alphabet.
So I want to find backslashes that exist in patterns like these:
\a
\f
\test
and not in these patterns:
\\a
\"
Thanks
Updated:
As #Amadan points out in the comments below, JavaScript does not implement lookbehind, which basically breaks my original answer.
There is an approach suggested in this stackoverflow post that may be a reasonable path to take for this problem.
Basically the poster suggests reversing the string and using lookahead to match. If we were to do that, then we would want to match a string of alphabetic characters followed by a single backslash, but not followed by multiple backslashes. The regex for that would look like this:
/[a-zA-Z]+\\(?![\\]+)/g
[a-zA-Z]+ - match one or more alphabetic characters
\\ - followed by a single backslash
(?![\\]+) - not followed by one or more backslashes
g - match it globally (more than one occurrence)
The downside of this approach (aside from having to reverse your string) is that you can't match only the backslash, but will have to also match the alphabetic characters that come before it (since JS doesn't have lookbehind).
Original Answer (using lookbehind):
/(?<!\\)\\[a-zA-Z]+/g (using negative lookbehind) will match a single backslash followed by one or more letters of the alphabet, regardless of case. This regular expression breaks down as follows:
(?<!\\)\\ - use negative lookbehind to match a \ that is not preceded by a \
[a-zA-Z]+ - match one or more letters of the alphabet, regardless of case
g - match it globally
If you only want to match the \ and not the alphabetic characters, then you can use positive lookahead. The regex for that would look like: /(?!>\\)\\(?=[a-zA-Z]+)/g and would break down like this:
(?<!\\)\\ - use negative lookbehind to match a \ that is not preceded by a \
(?=[a-zA-Z]+) - and is followed by one or more alphabetic characters
g - match it globally
If you only want the regex to match backslashes at the beginning of a line, prepend a ^ to it.
You can use a tool like Rubular to test and play with regular expressions.

Query on Javascript RegEx

I need a regex that allows 0-9, a-z, A-Z, hyphen, question mark and "/" slash characters alone. Also the length should be between 5 to 15 only.
I tried as follows, but it does not work:
var reg3 = /^([a-zA-Z0-9?-]){4,15}+$/;
alert(reg3.test("abcd-"));
length should be between 5 to 15 only
Is that why you have this?
{4,15}+
Just use {5,15}; it’s already a quantifier, and a + after it won’t work. Apart from that, the group isn’t necessary, but things should work.
/^[a-zA-Z0-9?/-]{5,15}$/
(I also added a slash character.)
This is what you need:
if (/^([a-z\/?-]{4,15})$/i.test(subject)) {
// Successful match
} else {
// Match attempt failed
}
REGEX EXPLANATION
^([a-z\/?-]{4,15})$
Options: Case insensitive
Assert position at the beginning of the string «^»
Match the regex below and capture its match into backreference number 1 «([a-z\/?-]{4,15})»
Match a single character present in the list below «[a-z\/?-]{4,15}»
Between 4 and 15 times, as many times as possible, giving back as needed (greedy) «{4,15}»
A character in the range between “a” and “z” (case insensitive) «a-z»
The literal character “/” «\/»
The literal character “?” «?»
The literal character “-” «-»
Assert position at the very end of the string «$»
Couple issues,
you need {5,15} instead of {4,15}+
need to include /
Your code can be rewritten as
var reg3 = new RegExp('^[a-z0-9?/-]{5,15}$', 'i'); // i flag to eliminate need of A-Z
alert(reg3.test("a1?-A7="));
Update
Let's not confuse can be with MUST be and concentrate on the actual thing I was trying to convey.
{4,15}+ part in /^([a-zA-Z0-9?-]){4,15}+$/ should be written as {5,15}, and / must be included; which will make your regexp
/^([a-zA-Z0-9?/-]){5,15}$/
which CAN be written as
/^[a-z0-9?/-]{5,15}$/i // i flag to eliminate need of A-Z
Also I hope everybody is OK with use of /i

Categories

Resources