Simply using a regular expression — e.g. using the sed command — for parsing formal languages won't cut it. It's much safer to use a processor that knows about the structure of the language.
For PHP, you can use the built-in tokenizer extension. It has the T_OPEN_TAG parser token, which matches <?php, <? or <%, and T_OPEN_TAG_WITH_ECHO, which matches <?= or <%=.
To replace all short open tags, you need to find all of these tokens and replace T_OPEN_TAG with <?php as well as T_OPEN_TAG_WITH_ECHO with <?php echo.
There are already some good scripts out there to convert PHP short tags into the good old long ones, of which I consider this one by Daniel Norton to be written quite well.
If you want to use such a script to convert a bunch of PHP files in some folder, this command comes quite handy:
find project/dir/ -type f -iname "*.php" -exec php -d short_open_tag=On php_replace_short_tags.php --overwrite {} \;
It recursively finds all PHP files in the folder project/dir/ and executes the PHP script for converting short tags you specify (in this example 'php_replace_short_tags.php' with the option --overwrite for each of these files.
It also switches short_open_tag=On while executing this command as otherwise the short tags could of course not be recognized.