【发布时间】:2015-06-07 07:00:47
【问题描述】:
我正在尝试查找和替换所有旧式 PHP 开放标签:<? 和 <?=。我已经尝试了几件事:
查找所有<? 字符串并将它们替换为<?php 并忽略XML
sudo grep -ri "<?x[^m]" --include \*.php /var/www/
这不会返回任何结果,因此所有以<?x 打开的标签都是 XML 开始标签,应该被忽略。
然后我对以<?p 开头但不是<?php 的标签做了同样的事情
sudo grep -ri "<?p[^h]" --include \*.php /var/www/
这返回了我手动编辑的一页 - 所以这将不再返回结果。所以我可以确定以<?p 开头的标签都是<?php,x 和xml 也是如此。
sudo grep -ri "<?[^xp]" --include \*.php /var/www/
查找更多不应被替换的开始标签
从这里开始,我可以运行上面的命令,看看会出现什么:空格、制表符、换行符、= 和{(可以忽略)。我认为\s 会处理空白,但我仍然得到很多结果。
尝试这样做会导致列表中带有标签的无穷无尽的列表:
sudo grep -ri "<?[^xp =}\t\n\s]" --include \*.php /var/www/
所以最后这没有用。我无法扫描数千行。这个表达有什么问题?如果某处<?jsp 存在并且不应该被替换,我想知道这一点,排除它,然后得到一个较短的列表,并重复此操作直到列表为空。这样我就确定我不会更改不应该更改的标签。
更新:^M
如果我在 Vim 中打开结果,我会看到 ^M,这是一个换行符。这可以直接在^M 在下面代码中的命令行上粘贴以下内容进行转义:使用 Ctrl+V, Ctrl+M 到enter a literal Carriage Return character into your grep string。这将结果减少到 1000 行。
sudo grep -ri "<?[^xp =}\t\n\s^M]" --include \*.php /var/www/
替换旧标签
如果这个表达式有效,我想运行一个 sed 命令并用它来替换旧的开始标签。
-
<?应该变成<?php(带结尾空格) -
<?=应该变成<?php echo(带结尾空格)
这会产生一个或多个这样的命令,首先替换 <?,然后是 <?=。
sudo find /var/www/ -type f -name "*.php" -exec sed -i 's/<?[^xp=]/<?php /g' {} \;
sudo find /var/www/ -type f -name "*.php" -exec sed -i 's/<?=/<?php echo /g' {} \;
问题
- 要使搜索 (grep) 和替换 (sed) 正常工作,我需要知道如何排除所有空格。在 Vim 中,我看到需要排除的
^M字符。 - 如果我的方法有误,请告诉我。欢迎所有建议。
【问题讨论】:
-
<?=不是老式的 php 标签 btw。 Starting with PHP 5.4, short echo tag <?= is always recognized and valid, regardless of the short_open_tag setting.。除非您使用的是旧版本的 php,否则最后一次查找和替换应该是相反的。您需要转义?字符。 -
感谢您解决这个问题!我也得到了替换它的建议,我在 Zend Framework 的评论中看到了关于将其转换为
<?php echo的内容。但这更容易,所以我可以保持原样。 -
也许你不应该使用正则表达式。您可以使用the
token_get_all()function,甚至a dedicated library 来修复这些问题。 nikic 的PHP-Parser 项目甚至有可能实现。 -
事实证明,过去人们认为
<?=会与 XML 规范发生冲突,但显然情况不再如此。见stackoverflow.com/questions/15847072/… -
我试图逃避
?,但这在这里不起作用。然后我得到无数错误的结果。我不知道为什么。