54

Are regex's allowed in PHP switch/case statements and how to use them ?

1
  • 2
    can you clarify this by giving an example of what you are trying to accomplish?
    – Adam
    Commented Oct 28, 2010 at 14:16

4 Answers 4

145

Switch-case statement works like if-elseif.
As well as you can use regex for if-elseif, you can also use it in switch-case.

if (preg_match('/John.*/', $name)) {
    // do stuff for people whose name is John, Johnny, ...
}

can be coded as:

switch $name {
    case (preg_match('/John.*/', $name) ? true : false) :
        // do stuff for people whose name is John, Johnny, ...
        break;
}
8
  • 14
    This only works when $name evaluates to true. If $name == '' this will yield wrong results. -1
    – NikiC
    Commented Oct 29, 2010 at 13:19
  • 9
    @nikic: you're right but this answers the OP's question : Are regex's allowed in PHP switch/case statements and how to use them ?
    – bourbaki
    Commented Oct 29, 2010 at 18:26
  • 2
    Took me a while to understand why this works. And I think it is an ugly hack. The key is that "most" strings validate to true. And the answer to the question would be: it works, most of the times.
    – Ezequiel
    Commented May 31, 2013 at 15:36
  • switch $name { case (preg_match('/e*/', $name)): echo "match";break;} shouldn't work correctly for $name = "" because preg_match('/e*', $name) is true but true != "".
    – Ezequiel
    Commented May 31, 2013 at 15:38
  • 2
    The preg_match() statement in case in the answer can be simplified as case (!!preg_match('/John.*/', $name)): Commented Jun 30, 2018 at 23:07
20

No or only limited. You could for example switch for true:

switch (true) {
    case $a == 'A':
        break;
    case preg_match('~~', $a):
        break;
}

This basically gives you an if-elseif-else statement chain, but with syntax and might of switch (for example fall-through.)

2
  • Thanks for your response. Then is it better (more readable) to do an if-elseif ?
    – Toto
    Commented Oct 28, 2010 at 15:21
  • 4
    @M42: If you don't want to fall-through (by not breaking) you should use if. It's cleaner.
    – NikiC
    Commented Oct 28, 2010 at 15:45
17

Yes, but you should use this technique to avoid issues when the switch argument evals to false:

switch ($name) {
  case preg_match('/John.*/', $name) ? $name : !$name:
    // do stuff
}
2
  • Thanks for your response. If i understand well, i can do preg_match("/regex/", $foo) ? true : false;. Can't I ?
    – Toto
    Commented Oct 28, 2010 at 15:23
  • 1
    The first example in this answer is better than all the other answers because it will always correctly match (or not) the subject of the switch(), whereas returning true or false from the preg_match() ternary could have unexpected results, as in @NikiC's empty string example.
    – Michael
    Commented Oct 24, 2011 at 7:43
5

Keep in mind the above answer can be slightly optimized like this:

Changing:

switch $name {
    case (preg_match('/John.*/', $name) ? true : false) :
        // do stuff for people whose name is John, Johnny, ...
        break;
}

To:

switch $name {
    case (bool)preg_match('/John.*/', $name) :
        // do stuff for people whose name is John, Johnny, ...
        break;
}

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