Finding all PHP short tags

For me this one worked fine:

<\?(?!php|xml)

Find

<\?(\t|\n|\s)

Replace

<?php$1

Explanation

Match only short tags <\?, followed by white-space, tab or newline (\t|\n|\s) and store it in $1

All of the solutions provided here match what the line doesn't contain, instead of what we know it will be guaranteed to contain. This allows your code formatting to remain identical, only adding the text php where needed.

We only ever want to match the short tag, and shouldn't care what comes after (php/xml/= etc). This find/replace will match both inline short tags and short tags on a separate line.

Note: If you're using Windows line-breaks, <\?(\t|\r\n|\s) will match the same.


The best way to find short-tags in vim is to find all occurrences of <? not followed by a p:

/<?[^p]

The reason your regex is failing in vim is because /? finds literal question marks, while \? is a quantifier; /<\? in vim will attempt to find 0 or 1 less-than signs. This is backwards from what you might expect in most regular expression engines.


If you want to match short tags that are immediately followed by a new line, you cannot use [^p], which requires there to be something there to match which isn't a p. In this case, you can match "not p or end-of-line" with

/<?\($\|[^p]\)

Using (a recent version of) grep:

grep -P '<\?(?!(php|xml|=))' *

To find all files with a <? short tag:

find -type f -exec grep -IlP '<\?(?!(php|xml|=))' {} +

Note that these do not match the <?= short tag, as that is always available since 5.4.0 and it does no harm either way. (Whereas <? does harm if allow_short_tags = Off.)

Tags:

Php

Vim

Regex