我试图更改为使用ZF1 / PEAR约定将我的php代码迁移到命名空间。
所以我想改变
$locale_test = (new ACME_Common_Factory())->createLocale(ACME_Common_Enum_Civility::MR);
到
$locale_test = (new \ACME\Common\Factory())->createLocale(\ACME\Common\Enum\Civility::MR);
我尝试使用以下sed程序(适用于只包含1个类名的行)
sed -r '/ACME/{h;s/ACME_.*$//1;x;s/^.*(ACME.*)$/\\\1/;s/_/\\/g;x;G;s/\n//1}'
但它实际上只做
sed -r '/ACME/s/_/\\/g'
我更喜欢使用sed或awk的解决方案(仅为了提高我的cli技能),但任何其他解决方案都可以。
答案 0 :(得分:1)
空格以及大多数特殊字符(但最重要的是,不是_
)会结束一个单词,因此我认为单词边界应该很好地识别类名。所以,使用GNU sed:
sed 's/\>/\n/g; :a s/\<\(ACME[^\n]*\)_\([^\n]*\)/\1\\\2/; ta; s/\<ACME/\\&/g; s/\n//g' filename
其工作原理如下:
s/\>/\n/g
在关闭单词边界后放置换行符。我们稍后使用它来匹配(有点)非贪婪。完成此步骤后,您的行将变为
$locale_test
= (new
ACME_Common_Factory
())->createLocale
(ACME_Common_Enum_Civility
::MR
);
这使我们能够轻松识别ACME名称空间中的名称:\<ACME[^\n]*
,并在ACME名称空间中标识包含下划线的名称:\<ACME[^\n]*_[^\n]*
。我们可以使用它来查找ACME名称中的下划线并逐个替换它们:
:a # jump label for looping
s/\<\(ACME[^\n]*\)_\([^\n]*\)/\1\\\2/ # Attempt replacement
ta # if it happened, go back to a.
之后,它只是
s/\<ACME/\\&/g
将\
放在前面,然后
s/\n//g
删除我们放在那里的换行标记。
请注意,我怀疑在Perl中这会更容易。
答案 1 :(得分:1)
这可能适合你(GNU sed):
sed -r ':a;s/(ACME[a-zA-Z\\]*)_/\1\\/;ta;s/ACME/\\&/g' file
答案 2 :(得分:0)
这个怎么样?
sed -r -e '/ACME_[^\(:]*/s/_/\\/g' -e 's/(ACME\\)/\\\1/g'
答案 3 :(得分:0)
我终于找到了@Wintermute启发的答案
sed -r ':a s/(ACME[^;:\(]*)_([^;:\(]+)/\1\\\2/g; ta' file