Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 855
  • Last Modified:

regex to match exact number of occurence of a sequence

Hello Experts,

I try to build a regex to match an exact number of occurence of a sequence/word :

For example "abc" and the number of occurence needed "3" and only three, no more no less

So :
abcXYZabcEFGabc match
abcXYZabcEFGabcKLMabc don't match because we find four time abc
abcXYZabcEFG don't match, only two is found
abcabcabc match

I have this : /^([^a]*a[^a]*){3}$/ but it work because I'm looking for "a" and not for a sequence "ab", "JPQ"

Thanks for your help!

Kinds Regards.
0
leakim971
Asked:
leakim971
  • 8
  • 7
  • 2
  • +2
4 Solutions
 
Patrick MatthewsCommented:
Does it have to be RegExp?

I don't know what specific language you are using, but if you:

1) Replace "abc" with "" and

2) The resulting string is 9 characters fewer in length than the original string

then you would have a "match".
0
 
leakim971PluritechnicianAuthor Commented:
Thanks a lot for your reply.
The language is Javascript and It sound stupid but I need to use a regexp.

Something like : /^([^a]*a[^a]*){3}$/.test("abcXYZabcEFGabc") will return true or false



0
 
Patrick MatthewsCommented:
Why must it be RegExp?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
phr0zeCommented:
Try this:

(abc[a-zA-Z]*?){3}(?!.*abc)

tested at regexpal.com
0
 
sentnerCommented:
Can you use 2 separate regex's?  For example, this pseudocode:

if /(abc.*){3}/ then
   if /(abc.*){4}/ return false     # More than 3 matches
   else return true                      # Exactly 3 matches
else return false                        # Less than 3 matches


0
 
leakim971PluritechnicianAuthor Commented:
Why a regex ? I can use it as a parameter for example.
@phr0ze and @sentner thank you I'm going to try your propositions.
0
 
käµfm³d 👽Commented:
@phr0ze

The problem with your pattern is that the *? on the bracket expression will consume any trailing "abc" strings after the first three. Simply adding the negative lookahead does not overcome this.
0
 
käµfm³d 👽Commented:
I believe the following satisfies the requirement:
^(?=(?:(?:[^a]|a[^ab])*abc){3}(?!.*?abc)).*$

Open in new window

0
 
leakim971PluritechnicianAuthor Commented:
kaufmed this one don't match : affkaabcsjfjabckfsofabc
affk a abc sjfj abc kfsof abc

0
 
käµfm³d 👽Commented:
It seems it did not upon further testing. Revised:
^(?=(?:(?:[^a]|a[^b]|a(?=a))*abc){3}(?!.*?abc)).*$

Open in new window

0
 
käµfm³d 👽Commented:
Yeah, the double-a killed it. The modified version has this corrected.
0
 
leakim971PluritechnicianAuthor Commented:
Don't match with : abffkabcsjfjabckfsofabc

ab ffk abc sjfj abc kfsof abc
0
 
käµfm³d 👽Commented:
Third time's a charm?

:)
^(?=(?:(?:a(?=a)|a[^b]|ab[^c]|[^a])*abc){3}(?!.*?abc)).*$

Open in new window

0
 
leakim971PluritechnicianAuthor Commented:
@kaufmed, yes it work this time, thanks. The "problem" with this regexp is the way we build it dynamically.
The original sequence need to have three characters for example : abc

Anyway I want to thank you a lot for your time. I'm going to use an array of regex+boolean and use the logic of @sentner

I'm going to close the question
Thank you to everyone for your suggestions, have a great weekend!
0
 
leakim971PluritechnicianAuthor Commented:
End of week, enjoy, have a nice weekend!
Thanks a lot to everyone! Have fun in your life!
0
 
käµfm³d 👽Commented:
I figured I'd throw this out there just in case, but the string shouldn't be that difficult to build dynamically; granted I don't know what your environment is like. Here is a function I created to build the pattern string:
function buildPattern(src)
{
	var basePattern = "^(?=(?:(?:@@@)*###){3}(?!.*?###)).*$";
	var temp = "";
	var t = src.charAt(0);
	
	for (i = 1; i < src.length; i++)
	{
		temp += "|" + t + "[^" + src.charAt(i) + "]";
		t += src.charAt(i);
	}

	temp = src.charAt(0) + "(?=" + src.charAt(0) + ")" + temp;
	
	return basePattern.replace(/###/g, src).replace(/@@@/, temp);
}

Open in new window

0
 
käµfm³d 👽Commented:
Of course, make sure your source strings don't contain the sequences "###" or "@@@"   :)
0
 
leakim971PluritechnicianAuthor Commented:
Thanks a lot @kaufmed!
0
 
käµfm³d 👽Commented:
Sure. Glad to help!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 8
  • 7
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now