Reputation: 22193
I need to check a string that must match:
1,2,3,4,5,6,7
So the rules are: only one number between 1 and 7, a comma separator, but I don't want repetition, so it's not legal to write:
1,2,3,1,5
Currently I'm using:
([1-7]{1},){1,6}([1-7]{1})
How can I modify it in order to check for repetition?
Upvotes: 5
Views: 3372
Reputation: 12075
I think @tobias_k is on the right track by suggesting that it's a good strategy to check for strings that have repetition, but I think you can have a more comprehensive regular expression that limits the character class and delimiter as you require.
Update: This version checks for occurrence of multiple digits.
([1-7]{1})(?:[1-7,])*\1|[^1-7,]+
([1-7]{1}),(?:[1-7]{1},)*(?:\1|[^1-7,]|(?:[1-7]{2,}))
1,2,3,4,5,6,7 // PASS: no match
1,2,3,4,5,6,8 // FAIL: matches out-of-bounds digit '8'
1,2,3,four,5,6,7 // FAIL: matches non-integer 'four'
1,2,3,1,5 // FAIL: matches repeating digit '1'
1,2,3,45 // FAIL: matches multiple digits
Upvotes: 2
Reputation: 82939
You can use \1
to refer to a formerly matched group (the first group in this case). Use this to find strings that have repetition.
The regex could look like this: .*\b(\d+)\b.*\b\1\b
.*
anything\b(\d+)\b
number between word delimiters (group 1).*
more anything\b\1\b
group 1 again between word delimitersExample in Python:
>>> p = r".*\b(\d+)\b.*\b\1\b"
>>> re.match(p, "1,2,3,4,5,6,7")
None
>>> re.match(p, "1,2,3,1,5")
<_sre.SRE_Match object at 0x8d2c2a0>
This will not check for those comma separators, though, so you'd have to do this in two steps: First check the general layout, then filter out those with repetitions.
Note, however, that the performance of this will probably not be good: It has to try each number for the first group, then match the string to see if there is another group that is the same as the first, then backtrack and try again, giving this O(n²) complexity. Instead, I suggest just using a set of already seen numbers and a loop.
Upvotes: 5