Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding Elvis ?:

Tags:

regex

I have been tasked to find Elvis (using eclipse search). Is there any regex that I can use to find him?

The "Elvis Operator" (?:) is a shortening of Java's ternary operator.

I have tried \?[\s\S]*[:] but it doesn't match multiline.
Is there such a refactoring where I could change Elvis into an if-else block?

like image 264
zeroin23 Avatar asked Jun 15 '09 08:06

zeroin23


2 Answers

You'll need to explicitly match line delimiters if you want to match across multiple lines. \R will match any of them(platform-independent), in Eclipse 3.4 anyway, or you can use the proper one for your file (\r, \n, \r\n). E.g. \?.*\R*.*: will work if there's only one line break. You can't use \R in a character class, though, so if you don't know how many lines the operator might span, you'd have to construct a character class with your line delimiter and any character that might appear in an operand. Something like ([-\r\n\w\s\[\](){}=!/%*+&^|."']*)\?([-\r\n\w\s\[\](){}=!/%*+&^|."']*):([-\r\n\w\s\[\](){}=!/%*+&^|."']*). I've included parentheses to capture the operands as groups so you could find and replace.

You've got a pretty big problem, though, if this is Java (and probably any other language). The ternary conditional ?: operator creates an expression, while an if statement is not an expression. Consider:

boolean even = true;
int foo = even ? 2 : 3;
int bar = if (even) 2 else 3;

The third line is syntactically incorrect; the two conditional constructs are not equivalent. (What you'd actually get from the second line if you used my regex to find and replace is if (int foo = even) 2 else 3; which has additional problems.)

So, you can find the ?: operators with the regex above (or something similar; I may have missed some characters you need to include in the class), but you won't necessarily be able to replace them with 'if' statements.

like image 28
super_aardvark Avatar answered Sep 29 '22 10:09

super_aardvark


Edit Sorry, I had posted a regex for the ternary operator, if your problem is multiline you could use this:

\?(\p{Z}|\r\n|\n)*:
like image 120
em70 Avatar answered Sep 29 '22 11:09

em70