Я пытаюсь изменить, чтобы перенести мой php-код с использованием соглашения ZF1 / PEAR в пространства имен.
Итак, я хочу изменить
$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 (просто для улучшения моих навыков), но подойдет любое другое решение.
Пробелы, а также большинство специальных символов (но, главное, не _
) завершение слова, поэтому я считаю, что границы слов должны служить для идентификации имен классов. Итак, используя 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.
Это может работать для вас (GNU sed):
sed -r ':a;s/(ACME[a-zA-Z\\]*)_/\1\\/;ta;s/ACME/\\&/g' file
Как насчет этого ?
sed -r -e '/ACME_[^\(:]*/s/_/\\/g' -e 's/(ACME\\)/\\\1/g'
Я наконец нашел ответ, вдохновленный @Wintermute
sed -r ':a s/(ACME[^;:\(]*)_([^;:\(]+)/\1\\\2/g; ta' file