3

I was wondering how can I match two digits but which are not the same. So, it would be fine to match 12, but not 11.

What I have till now is: I have to match strings like "P12", and I've done it with this regex:

^P([1-6]{1})([1-6]{1})$

But now my problem is how to match only strings like P12 or P32 where the numbers do not repeat.

Any help or guidance to reading materials will be grateful.

edit: Thank you all for your answers, but I was testing this in RAD (radsoftware.com.au/regexdesigner) - I know, I should have mentioned this :/, and most of it doesn't work there. I saw a solution posted from one user but this is not visible anymore, I don't know why, did he deleted it?? anyway: this is what worked:

^P([1-6]{1})(?!\1)([1-6]{1})$  

Thank you all!

Nikola
  • 14,888
  • 21
  • 101
  • 165
  • huh? You say you want to match numbers that "are not the same", then you say that 12 is cool and 11 is not; to me 12 and 11 seem precisely like numbers that "are not the same" – Ilya Saunkin Mar 10 '11 at 09:34
  • @Elijah, he means 12 (one two) is two different numbers while 11 (one one) are two of the same number. he wasn't comparing 11 to 12. – jb. Mar 10 '11 at 09:40
  • For your information, the user who deleted the answer left this message when they deleted it: "I refuse this answer as this [does not seem to work as expected in Safari](https://bugs.webkit.org/show_bug.cgi?id=56082)". The message is visible only to users with 10K or more reputation. – Mark Byers Mar 10 '11 at 10:48
  • @Mark: Thanx for the info. Strange, that answer was the only one working for me... – Nikola Mar 10 '11 at 11:01

5 Answers5

4

Use this:

^P((1[2-6])|(2[13-6])|(3[124-6])|(4[1-356])|(5[1-46])|(6[1-5]))$
Somnath Muluk
  • 55,015
  • 38
  • 216
  • 226
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • +1 but I guess, OP wanted to capture first digit and and second digit as seperate groups – YOU Mar 10 '11 at 11:29
  • this is the only correct answer.. why other answers has been upvoted?. – Gursel Koca Mar 10 '11 at 12:37
  • @Gursel: It is the only *universally* correct answer. But the other answers will work depending on what features the regex engine supports. – Ignacio Vazquez-Abrams Mar 10 '11 at 12:38
  • 1
    @ Ignacio Vazquez-Abrams : Well, it looks like the problem is related to negation of backreference. Most regular expression engines does not allow to use negation of backreferences. – Gursel Koca Mar 10 '11 at 12:53
3

You need to use backreferences. Essentially, you need to first match the first digit ([1-6]), store this match (using a pair of parentheses), and then use this reference to match anything but it ([^\1]), letters (A-Za-z), and 0, 7, 8, and 9:

P([1-6])[^\1A-Za-z0789]
João Silva
  • 89,303
  • 29
  • 152
  • 158
2

Try this

^P([1-6])([^\\1\D07-9])$

Tested on js shell

/^P([1-6])([^\\1\D07-9])$/.test("P12")
true
/^P([1-6])([^\\1\D07-9])$/.test("P11")
false

Other test cases

/^P([1-6])([^\\1\D07-9])$/.test("P10")
false
/^P([1-6])([^\\1\D07-9])$/.test("P1b")
false
/^P([1-6])([^\\1\D07-9])$/.test("P17")
false
YOU
  • 120,166
  • 34
  • 186
  • 219
  • `js> /P(\d)[^\\1]/.test("P1b")` `true` – Ignacio Vazquez-Abrams Mar 10 '11 at 09:34
  • Much closer. But it still lets `0` and `7-9` through. – Ignacio Vazquez-Abrams Mar 10 '11 at 09:37
  • Thank you for your answer, but I was testing this in RAD (http://www.radsoftware.com.au/regexdesigner/) and it doesn't work there. I saw a solution posted from one user but this is not visible anymore, I don't know why, did he deleted it?? anyway: this is what worked: ^P([1-6]{1})(?!\1)([1-6]{1})$ – Nikola Mar 10 '11 at 10:07
  • @Nikola: Different regex engines have different capabilities. The answer I posted will work even on "desert island" regex engines. – Ignacio Vazquez-Abrams Mar 10 '11 at 10:50
  • @Ignacio Vazquez-Abrams: Yes I am aware of that, I know, I should have stated which one I use. Thank you nevertheless for your contribution! – Nikola Mar 10 '11 at 11:00
  • @Nikola, Please try `\\D` instead of `\D`, looks like your regex software using .NET – YOU Mar 10 '11 at 11:37
2

JG is right, you want to use back references for this problem. So since we already have the correct answer, I just wanted to make one comment about your current regex:

^P([1-6]{1})([1-6]{1})$

the {m,n} means match the preceding thing at least m and at most n times. And {n} means match the preceding thing exactly n times. So when you put [1-6]{1} you're saying "match a single digit in the range 1-6 exactly once". It's redundant, you can simply say [1-6] by itself. so your regex could be simplified to:

^P([1-6])([1-6])$

this of course is not taking into account the disallowing duplicate number issue, but others have already solved that problem.

jb.
  • 9,921
  • 12
  • 54
  • 90
1

I think you need to learn backreference. It allows you to see whether previously matched group and currently matched group is same. You can get more information about it here

Shekhar
  • 11,438
  • 36
  • 130
  • 186