Regex, That Matches No more Than n Occurrences
Asked Answered
M

2

7

I'm trying to find a Regex, that matches no more than n consecutive, say three, for example, occurrences of a character; in the case of three and character is "a":
abbaa - matches;
ammaaa - doesn't match(three consecutive a's), there is one "a", but whole expression must be discarded because three "a's"

Thank you.

Marou answered 2/4, 2017 at 22:54 Comment(3)
What have you tried? What regex engine are you using?Blastopore
Read some tutorials and experimenting on regex101.Marou
For those cases where you know n is 1, a simple question mark will suffice. a? matches zero occurrences and one occurrence of the letter a.Loupe
R
3

You can specify a character, or you can generalize it to all characters.
Also, not sure if you're trying to test or match the whole string, but assume
it's the whole string.

Generalized

^(?:(\w)(?!\1{2})|\W)+$

Explained

 ^                       # Beginning of string
 (?:                     # Cluster
      ( \w )                  # (1), a word character
      (?! \1{2} )             # Not 2 more of same in a sequence
   |                        # or,
      \W                      # Not a word character
 )+                      # End Cluster, 1 to many times
 $                       # End of string

You could substitute specific characters instead of \w and \W
by replacing what you want.

Example for character a it would be a and [^a].

^(?:(a)(?!\1{2})|[^a])+$

or more than one like [abc] and [^abc]

^(?:([abc])(?!\1{2})|[^abc])+$

Robinett answered 2/4, 2017 at 23:35 Comment(2)
@TomaszMadry - Added an update note for specific character(s).Robinett
Thanks, seems to be this:)Marou
S
20

Use the {m,n} syntax (if your environment provides it, which it likely does.

{m,n} allows m to n (inclusive) occurrences of the previous character.

Examples:

/a{0,3}/ matches 0 to 3 occurrences of a.

/a{3,}/ matches 3 or more occurrences.

/a{3}/ matches exactly 3 occurrences.

In the following example I've paired the above syntax with negative lookahead and negative lookbehind.

(?<!a)a{0,3}(?!a) matches 0 to 3 occurrences of a where there is no a before or after those 0-3 occurrences.

Spam answered 2/4, 2017 at 23:10 Comment(8)
But the first example /a{0,3}/, matches also, let's say: xxaaaad; regex101.com/r/f54igA/1Marou
Right, you have to be more specific with what you want to match if you want me to prescribe exact solutions. You would use the syntax I mentioned to build whatever regex you wanted. See my updated answer for another example.Spam
Let me know if that last example is what you are looking for. I'm happy to discuss further and edit my question. Regexes are fun.Spam
That works, cool. Interesting, that I've missed those negative looks syntax. I'm searching and reading now. Cheers.Marou
Well, but still accepts abaaa - because of "a" in the expression; another answer seems to solve it.Marou
It should match abaaa. It will match no more than 3 and that satisfies it. The look behind and look ahead are making sure there is not another a directly before the group of 0-3 a's. For example aaaa won't be accepted. Actually, the example in your question statement is wrong. No more than 3 consecutive means 3 in a row IS allowed.Spam
Yes, about no more than three is a typo mistake, but problem is how to make it to not accept abaaaa - because there is more than three "a's".Marou
Let us continue this discussion in chat.Marou
R
3

You can specify a character, or you can generalize it to all characters.
Also, not sure if you're trying to test or match the whole string, but assume
it's the whole string.

Generalized

^(?:(\w)(?!\1{2})|\W)+$

Explained

 ^                       # Beginning of string
 (?:                     # Cluster
      ( \w )                  # (1), a word character
      (?! \1{2} )             # Not 2 more of same in a sequence
   |                        # or,
      \W                      # Not a word character
 )+                      # End Cluster, 1 to many times
 $                       # End of string

You could substitute specific characters instead of \w and \W
by replacing what you want.

Example for character a it would be a and [^a].

^(?:(a)(?!\1{2})|[^a])+$

or more than one like [abc] and [^abc]

^(?:([abc])(?!\1{2})|[^abc])+$

Robinett answered 2/4, 2017 at 23:35 Comment(2)
@TomaszMadry - Added an update note for specific character(s).Robinett
Thanks, seems to be this:)Marou

© 2022 - 2024 — McMap. All rights reserved.