2016-11-15 5 views
2

Ich habe einige wirklich alten Code (PHP 5.1), die auf einem neueren Server ausgeführt werden muss.Sed zum Ersetzen <? mit <? php

Neuer Server hat PHP 5.6, so dass alle Bereiche, in denen

<? 

verwendet werden, um den PHP-Kontext zu öffnen, werden diejenigen, die nicht korrekt interpretiert werden. Ich brauche alle Instanzen

<? 

mit

<?php 

außer wo

<? 

bereits Teil

ersetzen
<?php 

Mein inital Aufwand war Rückreferenzierungen zu verwenden und sed:

cat file.php | sed -i 's/<?([^php])/<?php\$1/g' 

jedoch die() scheint das Spiel zu brechen, und ohne sie kann ich nicht einen richtigen Rückbezug habe.

Ich habe versucht, was nach PHP Starttag in die Rückreferenzierung, so konnte ich zu bekommen war drehen Zeilen wie:

<?=$_COOKIE... 

in

<?php=$_COOKIE... 

Und bitte nicht Punkt mich an: Using sed to replace <? with <?php. Ich habe es schon gesehen, und es spricht nicht die Tatsache an, dass ich an manchen Orten bereits das neue Eröffnungs-Tag und in anderen das alte Eröffnungs-Tag habe. (Eine der Antworten irgendwie tut, aber ich würde es vorziehen, nicht zu erstellen "phpphphphpphp" und müssen immer wieder nach "php"

suchen

Schließlich, bitte verzeihen Sie die seltsam verteilt offenen und schließenden Tags . SO kann sie nicht nur in Zeile angezeigt werden mit dem Text, wenn sie in einem Codeblock sind

+2

'[^ php]' stimmt nicht mit einem Text überein, der nicht mit 'php' übereinstimmt, er passt nur zu 1 Zeichen, das entweder' p' oder 'h' ist. IMHO, das kann man mit sed regex nicht zuverlässig machen, da es Lookarounds nicht unterstützt. –

+1

Die richtige Regex wäre etwas wie diese "<\? (?! PHP"), aber wie @ WiktorStribiżew angegeben, 'sed' unterstützt keine negativen Lookaheads. –

+0

Ich war mir nicht bewusst, dass es negative Blickwinkel nicht unterstützt. Sieht aus, als müsste ich das in Python schreiben ... Danke, meine Herren. – DrDamnit

Antwort

1

Sie tun können:.

sed 's/<?\(php\)*/<?php/g' file 

in diesem Fall „php“ ist optional, aber systematisch überschreibt, wenn es bereits ist hier

Oder mit einem Leerzeichen-Zeichen r wie abracadaver schlägt vor, da es nach einem kurzen Tag obligatorisch zu sein scheint:

sed 's/<?\([[:space:]]\)/<?php\1/g' file 

Einschränkung: dieses Muster kann nicht wissen, ob <? oder <?php in einem String ist.Beispiel:

echo 'abc <? def'; 

wird:

echo 'abc <?php def'; 

Ein besserer Weg ist PHP selbst mit dem tokenizer zu verwenden.

Beispiel:

$str = 'echo "blah"; <? echo "sblub"; ?> bluh'; 

$result = ''; 

foreach(token_get_all($str) as $tok) { 
    $result .= ($tok[0] == 376) ? '<?php' : $tok[1]; 
} 

echo $result; 
+0

Ich kenne SED nicht, aber warum nicht ersetzen' AbraCadaver

+0

weil manchmal Leerzeichen vorhanden sind und manchmal nicht. – DrDamnit

+0

@AbraCadaver: Es ist eine gute Idee mit '[[:: blank:]]' anstelle von '\ s', aber ich erinnere mich nicht, ob '' Erlaubt war oder nicht. –

0

können Sie versuchen, diese https://regex101.com/r/tMkwCT/1

regex:

^<\?([^p\=])/gm 

Substitution:

<?php$1 

exp lanation:
^behauptet Position am Anfang einer Zeile
< entspricht das Zeichen < buchstäblich (Groß- und Kleinschreibung)
\? passt der Charakter? buchstäblich (Groß- und Kleinschreibung)
1. einfangende Gruppe ([^ p \ =])
Spiel ein einzelnes Zeichen nicht in der Liste unten [^ p \ =]
p entspricht dem Zeichen p buchstäblich (Groß- und Kleinschreibung)
\ = entspricht dem Zeichen = wörtlich (Groß-/Kleinschreibung beachten)
Globale Musterflags
g Modifizierer: global. Alle Treffer (nicht nach dem ersten Treffer)
m Modifizierer: multi line. Ursachen^und $ passen Beginn/Ende jeder Zeile (nicht nur zu Beginn/Ende des Strings)

Sie für Ihre SED-Skript ändern können

oder Sie short_open_tag http://php.net/manual/en/language.basic-syntax.phptags.php

PHP also allows for short open tag <? (which is discouraged since it is only available if enabled using the short_open_tag php.ini configuration file directive, or if PHP was configured with the --enable-short-tags option).

aktivieren

Update:
- https://regex101.com/r/tMkwCT/4 von @SamuelAialaFerreira
- https://regex101.com/r/tMkwCT/7 - Entfernen^so wird es, wenn die offene überprüfen Der Code steht nicht am Anfang einer Zeile

+0

Das hat fast für mich funktioniert. Ich versuche, dieses Skript in einem riesigen Ordner zu laufen, und in diesen beiden Fällen haben sie nicht funktioniert

+1

Ich änderte auch das äh zu^<\? ([^ PP \ =]), weil Sie