lollerskates
lollerskates

Reputation: 1147

Correct regex for matching EXACTLY n instances of a pattern

Let's say I have the following:

1.) /some/text/here/with-dashes/010101/
2.) /some/text/here/too/
3.) /some/other/really-long/text/goes/here/019293847/

I want to get the strings that contains EXACTLY 6 / so far these regex aren't working how I intended it to:

(/\w+[-]?\w+){6}
(/\w+[-]?\w+){6,6}
(/\w+[-]?\w+){,6}?

These regex also matches strings with more than 6 / I want it to match strings with EXACTLY 6 /.

Upvotes: 1

Views: 2302

Answers (2)

pylang
pylang

Reputation: 44465

Consider more_itertools.exactly_n a third-party library.

Code

iterable = "1.) /some/text/here/with-dashes/010101/"
pred = lambda x: x == "/"
n = 6

mit.exactly_n(iterable, n, pred)
# True

Tests

f = mit.exactly_n

assert f("1.) /some/text/here/with-dashes/010101/", n, pred) == True
assert f("2.) /some/text/here/too/", n, pred) == False
assert f("3.) /some/other/really-long/text/goes/here/019293847/", n, pred) == False

Upvotes: 0

kindall
kindall

Reputation: 184091

The correct syntax for exactly six matches is {6} as in your first example.

The reason that the regexes you're using are matching more than six occurrences of your target string is that they aren't anchored to the beginning and end of the string. If a string has (say) ten occurrences of path components, it matches the first six, so that counts.

To fix this, use e.g.:

^(/\w+[-]?\w+){6}$

Or to allow an optional closing slash:

^(/\w+[-]?\w+){6}/?$

Upvotes: 6

Related Questions