Оставьте тяжелую работу для IDE.
Примечание. Эта статья не ставит целью дать исчерпывающий набор правил для автоматического преобразования файлов локализации — я хочу лишь показать, как с помощью поиска и замены можно выиграть время.
Сегодня у меня была простая, но скучная задача: использовать переведенный текстовый контент из проекта для iOS в приложении для Android.
Есть SaaS-инструменты, которые могут взять эту задачу на себя, — например, Phrase, но не каждый захочет платить за это. Кроме того, если не начать работать с такой платформой заранее, вам всё равно придется потратить чересчур много времени на импорт контента — правда, вроде бы есть какие-то инструменты для загрузки.
В общем, в рамках этой статьи мы для работы с переведенным контентом не будем использовать внешние инструменты.
Как разработчик вы должны знать, что файлы локализации в iOS и Android различаются. В iOS мы увидим что-то вроде такого:
Localizable.strings
//Комментарий
"key_1" = "What a %@ task, don't you think?";
(«Очень %@ задача, вам так не кажется?») А в Android — такое:
strings.xml
<!-- Комментарий -->
<string name="key_1">What a %s task, don\'t you think?</string>
Кроме собственно типа файла (strings для iOS, XML для Android) легко заметить и другие различия. Я специально использовал динамический строковый параметр: в него можно подставить tedious (скучная) или exciting (захватывающая) — вам решать!
Посмотрим, что же нужно изменить и как это сделать.
Совместимость локализованного файла с Android
Для переноса этого файла iOS в проект Android необходимо сделать следующее:
Изменить ключ и синтаксис связанного с ним значения.
Адаптировать динамический параметр.
Экранировать специальные символы (например, ').
Преобразовать комментарии в XML.
Напомню, что это — всего лишь пример того, что нужно будет изменить.
Сначала нам придется изменить префикс и суффикс, чтобы они содержали ключ и значение в формате XML.
Префикс "key_1" =
" превратится в <string name="key_1">
.
Суффикс ";
— в </string>
.
Динамический параметр %@
будет выглядеть как %s
. Для большинства других динамических типов (например, целые и десятичные числа) используется одинаковый синтаксис. Мой пример упрощен: в нем используется только один динамический параметр, но об этом позже.
Android Studio будет жаловаться на неэкранированные символы — например '
, — и скажет экранировать их с помощью обратной косой черты \
.
Наконец, если в файле iOS есть комментарии, их также нужно преобразовать, поскольку в XML другой синтаксис: //Comment
должен выглядеть как <!-- Comment -->
.
Всё хорошо, но мы преобразовали только одну строку нашего файла… А вам наверняка нужно будет перенести тысячи строк — тут легко будет запутаться. Вполне возможно, и языков у вас будет много, поэтому адаптация строк вручную может занять слишком много времени.
Вы наверняка догадываетесь, что это можно автоматизировать с помощью скриптов. Но знаете ли вы, что всё необходимое уже есть в той IDE, которую вы используете для разработки приложения?
Я имею в виду одну из наиболее часто используемых функций любой IDE — «поиск и замена». Нам, правда, понадобятся регулярные выражения.
Преобразование с помощью регулярных выражений
Выше мы уже описали все этапы преобразования файла — осталось только найти правильный инструмент для применения этих правок ко всему содержимому файла.
Эффективнее было бы написать скрипт (например, на Питоне), но давайте предположим, что вы не знакомы со скриптами и вас полностью устраивает IDE.
Некоторые описанные выше операции не требуют регулярных выражений:
суффикс,
специальный символ
'
,синтаксис параметров.
В этих случаях хватит и обычного поиска и замены.
Остальное — это динамический контент, для которого обычного поиска и замены не хватит, поэтому нам понадобятся регулярные выражения. В Android Studio они включаются здесь:
Теперь нам нужно подобрать регулярное выражение, которое будет извлекать необходимые фрагменты, а также понять, как IDE хранит копию извлеченного фрагмента.
Для получения префикса мы будем извлекать имя ключа и преобразовывать его с учетом нужного синтаксиса. Ключ обычно представляет собой одно слово, поэтому выражение может быть достаточно простым: "(\w+)" = "
. Затем мы делаем замену на нужный нам синтаксис: <string name=”$1">
, где $1
содержит аргумент, найденный с помощью регулярного выражения. Android Studio подсказывает, как будет выглядеть замененный префикс.
Это выражение можно спокойно применить ко всем вхождениям префикса.
Наконец, если у вас есть комментарии, преобразуйте их по такому же принципу. В комментариях может быть не одно слово, поэтому следует использовать более гибкое регулярное выражение, например //(.*)
.
Вот и всё! Понятно, что подобные преобразования не охватывают всех случаев — может понадобиться что-то сделать вручную.
Например, если есть несколько параметров с одним и тем же значением, Android требует присваивать индекс, тогда как iOS — нет.
Localizable.strings
"key_2" = "%@ gave %d claps for this article";
примет следующий вид:
strings.xml
<string name="key_2">%1$@ gave %2$d claps for this article</string>
Преобразования в этой статье были исключительно в качестве примера. Я в целом настоятельно рекомендую не забывать о таком мощном инструменте, как поиск и замена с использованием регулярных выражений, при выполнении таких затратных по времени задач, как эта: вы сэкономите время — и сохраните здравомыслие!
Хотелось бы выразить благодарность Анупаму Чу.
О переводчике
Перевод статьи выполнен в Alconost.
Alconost занимается локализацией игр, приложений и сайтов на 70 языков. Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов.
Мы также делаем рекламные и обучающие видеоролики — для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.