Your task here is to write two regular expressions, each of which matches the other one but does not match itself.

Both regular expressions should have this form:


This is also the form in which they should be matched.

The shortest solution wins. The solution length is counted as the sum of characters in both regular expressions including slashes and flags.

Use a regex syntax standard of your choice, or specify a programming language, when it makes a difference.

Have fun!

  • \$\begingroup\$ Does the regex also have to match the slashes and flags of the other regex? \$\endgroup\$ – ProgramFOX Mar 2 '14 at 15:30
  • \$\begingroup\$ @ProgramFOX yes, I added a line to make it clear. \$\endgroup\$ – GOTO 0 Mar 2 '14 at 15:35
  • \$\begingroup\$ Can you define match? i.e. does the regex /a/ match abc? \$\endgroup\$ – The Guy with The Hat Mar 2 '14 at 20:05
  • 2
    \$\begingroup\$ @TheGuywithTheHat well, I think so, unless you choose a language that imposes certain restrictions, like the need to match the whole string. Does this address your concern? \$\endgroup\$ – GOTO 0 Mar 2 '14 at 20:21
  • 1
    \$\begingroup\$ To be clear: I assume that the use of different delimiters (as permitted by e.g. PHP PCRE) is not permitted? (I.e. no submitting /^%/ and %^/%) \$\endgroup\$ – Peter Taylor Mar 3 '14 at 9:27

11 Answers 11


PRCE with the A modifier: 9 chars


Although this is a variant on Doorknob's /modifier$/ answer, I think this innovation qualifies it as a separate answer rather than a comment on his: the modifier does double-duty. Rather than being there solely for the other regex to match, it anchors.

The first regex matches any string ending in a literal A. The second regex matches any string whose second character is a literal A, using an anchor-to-start flag.

Online demo

  • 3
    \$\begingroup\$ To beat this requires only four non-delimiter chars, and since // matches anything that means that each of the regexes can have at most three non-delimiter chars. Using PHP PCRE there are 73339 non-self-matching regexes within that constraint, and exhaustive checking of the pairs whose length is less than 10 (on the order of 32Mpairs rather than 5.7Gpairs because most of them are 5 chars including delimiters) turns up this solution and no others. I therefore claim that it is optimal for that particular regex engine. \$\endgroup\$ – Peter Taylor Mar 3 '14 at 16:11

4+6=score of 10

First regex:


Second regex:


Hooray for flag abuse! :-P

The first one matches anything that ends with i (therefore, any regex with the i flag).

The second one matches anything with a second character of i.

Alternative version: /i$/g and /g$/i.

  • 3
    \$\begingroup\$ Another variation would be /x.$/ and /^.x/ for a bunch of x \$\endgroup\$ – shiona Mar 2 '14 at 21:52
  • \$\begingroup\$ Or /i$/ and /\/$/i \$\endgroup\$ – Peter Taylor Mar 2 '14 at 23:29
  • \$\begingroup\$ Or /i$/ and /i\$/i \$\endgroup\$ – Peter Taylor Mar 3 '14 at 8:16

JavaScript regexes, score: 18

First regex:


Second regex:


JavaScript test:

var regex1 = "/^[^a]+$/";
var regex2 = "/^[^b]+$/";
alert(/^[^a]+$/.test(regex2)); // true: regex1 matches regex2
alert(/^[^b]+$/.test(regex1)); // true: regex2 matches regex1
alert(/^[^a]+$/.test(regex1)); // false: regex1 doesn't match regex1
alert(/^[^b]+$/.test(regex2)); // false: regex2 doesn't match regex2

Test online: http://jsfiddle.net/99Sx6/


Ruby regex, 15

Regular expressions:


Just counting characters...

Online version

r1 = '/.{9}/'
r2 = '/^.{06}$/'

p r1 =~ /^.{06}$/ #0:   r2 matches r1
p r2 =~ /.{9}/    #0:   r1 matches r2
p r1 =~ /.{9}/    #nil: r1 doesn't match r1
p r2 =~ /^.{06}$/ #nil: r2 doesn't match r2

4 + 6 = 10

First regex:


Second regex:


i$ matches something that ends with i, the second one. /$ matches something that ends with /, the first one.

  • 2
    \$\begingroup\$ Dupe of a comment I posted to Doorknob's answer. \$\endgroup\$ – Peter Taylor Mar 3 '14 at 8:09
  • \$\begingroup\$ @PeterTaylor Didn't notice the comments until now. These were independent discoveries. \$\endgroup\$ – Justin Mar 3 '14 at 18:11
  • \$\begingroup\$ Yeah, I independently discovered shiona's version too. \$\endgroup\$ – Peter Taylor Mar 3 '14 at 19:09

5 + 5 = 10

Regex #1:


Regex #2:


The 0s in both regexes can be replaced with any non-metacharacter and the regex still works.

0.$ matches anything whose second last character is 0, and ^.0 matches anything whose second character is 0.

  • 2
    \$\begingroup\$ The first pair aren't valid regexes: you need to escape the /es. The alternative is a dupe of a comment on Doorknob's answer. \$\endgroup\$ – Peter Taylor Mar 3 '14 at 8:13

JavaScript regexes, score: 13

First regex:


Second regex:


Explanation: the first regex matches everything that contains a digit, and the second regex matches everything that doesn't contain a 0.

JavaScript test:

var regex1 = "/\d/";
var regex2 = "/^[^0]+$/";
alert(/\d/.test(regex2)); // true: regex1 matches regex2
alert(/^[^0]+$/.test(regex1)); // true: regex2 matches regex1
alert(/\d/.test(regex1)); // false: regex1 doesn't match regex1
alert(/^[^0]+$/.test(regex2)); // false: regex2 doesn't math regex2

Test online: http://jsfiddle.net/5VYjC/1/


12 chars ;) JS regex


Score: 5 + 5 = 10

Took me half-an-hour to figure out but I am really happy that I did :)

1st is: /j.$/

2nd is: /^.j/

The 1st matched a j occurring in the second position starting from the right. The 2nd matches a j occurring at the second-position starting from left.

I haven't tested but I think that these RegExs are really versatile as the j can be replaced with any \w character (or more?) and still should work fine.

P.S. This should (hopefully) work in any language. Though, if it does not work in any, please inform in the comments below :)


  • \$\begingroup\$ And I figure out now that @Quiccunx has already posted the same version as mine. I am really sorry Quiccunx and if it shall please any, I shall delete my answer. \$\endgroup\$ – Gaurang Tandon Mar 4 '14 at 13:07

PCRE using modifier x: 11 chars

/ s.$/x

The first matches any string with a whitespace character, but doesn't contain whitespace. The second contains whitespace, but it's ignored because of the x modifier; it matches any string whose penultimate character is s.

PCRE and other engines using character classes: 11 chars


The first matches any string with a "word" character (letter, digit, underscore) followed by a literal w; the second matches any string with a non-word character followed by a literal w.

PCRE and other engines using character classes and word boundary anchor: 11 chars


The first matches any string with two consecutive "word" characters; the second any string with a non-word character or start of string followed by a literal w.


ECMAScript (11 bytes):


Other REGEXP Engines (14 bytes):


The 1st matches \d[..] or \1d[..].

The second matches any string with a number.


Originally, this answer was posted as being compatible with all engines, but it was proven to be wrong.

There was a problem with references to the capturing groups (for example, in php).

  • \$\begingroup\$ Many regex engines take the regex without surrounding slashes, but the question is quite clear in requiring them to be counted. \$\endgroup\$ – Peter Taylor Mar 2 '14 at 23:43
  • \$\begingroup\$ I am not counting it as an answer. Let me add the note for that. \$\endgroup\$ – Ismael Miguel Mar 2 '14 at 23:45
  • 1
    \$\begingroup\$ @PeterTaylor I added the note. The Apache version is there just because. \$\endgroup\$ – Ismael Miguel Mar 2 '14 at 23:50
  • \$\begingroup\$ Hang on: in what engines does the first one parse with \1 not interpreted as a back-reference? \$\endgroup\$ – Peter Taylor Mar 2 '14 at 23:51
  • \$\begingroup\$ Depending on the way you use it. In php, for example, if you put inside "/^\1?d/" you will have trouble, but if you do '/^\1?d/', then it's fine. The quotes make a huge difference when the code is interpreted. \$\endgroup\$ – Ismael Miguel Mar 2 '14 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.