regexp in switch statement
Asked Answered
L

4

54

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

Licence answered 28/10, 2010 at 14:13 Comment(1)
can you clarify this by giving an example of what you are trying to accomplish?Palmapalmaceous
O
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;
}
Orleanist answered 28/10, 2010 at 18:26 Comment(8)
This only works when $name evaluates to true. If $name == '' this will yield wrong results. -1Gerfalcon
@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 ?Orleanist
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.Seamount
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 != "".Seamount
To save a few keystrokes, you can simply use: case 1 == preg_match('/john.*/', $name): Manage
If $name doesnt evaluate to true, a workaround would be case (preg_match('/John.*/', $name) ? $name : !$name) : to make sure you always match the switch on regex match, even if its a sign that you should be doing this in a different way.Decoct
Old thread but still, "case" is meant to evaluate a single value and execute what it's after, untill "break". Want more matches same code, use multiple "case" one after another. Don't try to use condition as "case" evaluation, "case" itself it's an evaluation, won't work as expected.Spherics
The preg_match() statement in case in the answer can be simplified as case (!!preg_match('/John.*/', $name)):Balikpapan
G
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.)

Gerfalcon answered 28/10, 2010 at 14:49 Comment(2)
Thanks for your response. Then is it better (more readable) to do an if-elseif ?Licence
@M42: If you don't want to fall-through (by not breaking) you should use if. It's cleaner.Gerfalcon
C
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
}
Chemotropism answered 28/10, 2010 at 14:18 Comment(2)
Thanks for your response. If i understand well, i can do preg_match("/regex/", $foo) ? true : false;. Can't I ?Licence
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.Socle
W
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;
}
Wingfield answered 30/11, 2021 at 9:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.