NPJ next: Документация/ТранслитерацияURLАдреса ...

Главная | Каталог | Изменения | НовыеКомментарии | Пользователи | Вам запрещён доступРегистрация | Вход:  Пароль:  

Транслитерация URL-адреса: задачи и решения


Оглавление документа


Эта статья о том, что такое «транслитерация URL-адреса», зачем она нужна и какие её виды нами используются. В статье рассказывается про «взаимно-однозначный транслит», а также приводятся другие интересные наборы правил для транслитерации адресов формата URL.

1. О чём речь

Почти всем из нас, кто решал проблему автоматической или полу-автоматической генерации «удобных для человека URL-адресов» (их ещё называют «ЧПУ» или pretty-urls), приходилось сталкиваться с задачей так называемой «транслитерации URL-адреса».

Эта задача имеет следующие ограничения и стартовые условия:

  1. URL-адреса страниц могут состоять из ограниченного набора символов: цифр 0–9, латинских букв a-z и A-Z, слэша /, тильды ~ и следующих символов, указанных в  RFC 2396: -_.!*'()
  2. То, из чего мы должны программным путём сгенерировать URL — как правило, заголовок новости. Или документа. Словом, может включать и русские буквы, и знаки препинания, и почти всё, что угодно, включая HTML-таги.

Если разобраться, то перед нами встаёт не одна задача, а целых три:


  1. Получение красивого читаемого адреса URL — задача, в которой мы жертвуем дотошностью в угоду красивости.
  2. Формирование короткого однозначного идентификатора (мы его привыкли называть «супертагом») — задача, в которой мы жертвуем красивостью ради борьбы с опечатками.
  3. Передача англо-русскоязычного слова (или фразы) через URL без потерь — для последующего восстановления исходного «текста» (слова или фразы). Именно эта задача и получила название «взаимно-однозначный транслит», и жертвует красивостью ради однозначности преобразования.

Для решения этих трёх разных задач мы разработали три разных способа транслитерации. Кроме того, мы разработали пару классов на языках PHP и JavaScript, осуществляющих все эти три способа. Ссылку на этот проект с открытым исходным кодом вы найдёте в самом низу документа.

2. URL Translit: Красивый читаемый URL-адрес

Красивый читаемый адрес нам нужно формировать автоматически для новостей, документов, статей, — как правило, на основе заголовка, формат которого мы условно называем «что-угодно». Т.е. там нам могут встретиться не только недопустимые в URL русские буквы, но ещё и знаки препинания.

Нам нужно добиться от автоматики такого преобразования, чтобы результат легко читался, не вызывая затруднений и недоумений. Такое преобразование мы называем «урл-транслит», а его результат, обычно, pretty_url.

2.1. Постановка задачи

Из чего-угодно™ получать валидный урл, URL, который легко «прочитать» — понять содержимое, глядя на него в адресной строке или в строке, теле страницы или статус-баре.

Не требуется восстановление исходного чего-угодно™.

2.2. Критерии, которые актуальны для данной задачи


2.3. Решение


Решение реализовано на двух языках программирования (PHP и JavaScript), содержится в открытом проекте Translit.
Метод называется UrlTranslit().

3. Supertag Translit: Короткий однозначный идентификатор

Если то, о чём мы говорили раньше, своей первой и наиглавнейшей задачей ставило «понятность» адреса для читателя-человека, то задача номер два — уметь формировать адреса-идентификаторы (т.е. такие, по которым мы будем находить, скажем, в БД ту новость, которую следует показать).

Адрес-идентификатор в виде числа часто недостаточен для читателя-человека (например: http://somesite.ru/page/34722), поэтому его можно сопровождать «красивым и понятным» дополнением, которое наш программный механизм будет игнорировать (например, страница с адресом http://www.npj.ru/kuso/259318_dve_trenirovki_podrjad показывает то же, что и  http://www.npj.ru/kuso/259318).

Однако, часто такое решение недостаточно, — ставится дополнительное условие «никаких цифр». Тогда нам ничего не остаётся, как использовать «красивое и понятное» дополнение в качестве идентификатора. В таком случае нам хочется обезопаситься хотя бы от того, что при переписывании забудут написать подчёркивание _ или напишут два подчерка вместо одного. Длину ключа тоже хочется сделать поменьше — дабы хоть немного ускорить поиск/сравнение строк. Такой ключ мы привыкли называть супертагsupertag.

3.1. Постановка задачи

Из чего-угодно™ получить максимально короткий идентификатор, который не не теряет смысла/однозначности и вместе с тем некритичен к лишним разделителям и большим/малым буквам.

Не требуется восстановление исходного чего-угодно™.

3.2. Критерии, которые актуальны для данной задачи


3.3. Решение

Решение реализовано на двух языках программирования (PHP и JavaScript), содержится в открытом проекте Translit.
Метод называется Supertag().

4. BiDi Translit: Взаимно-однозначный транслит

В качестве исторического экскурса можно заметить, что вся эта «эпопея» с транслитерацией началась в своё время с постановки задачи «взаимно-однозначного транслита» — когда возникла необходимость передавать в URL-совместимом формате информацию таким образом, чтобы её можно было однозначно восстановить обратным преобразованием.

Передаваемая информация включала в себя только буквы, цифры, дефис и «слэш» /. Это — именно та функциональность, которая используется в НПЖ при формировании ссылок на создание новых страниц. Для формирования «красивых» ссылок на уже существующие страницы используется «урл-транслит», а в БД хранятся «супертаги».

4.1. Постановка задачи

Из строки, содержащей русские и английские буквы, получать валидный URL (без использования %AB-комбинаций), таким образом, чтобы затем было возможно восстановить оригинальную строку. Также уметь производить и обратную операцию.

В отличие от предыдущих рассмотренных способов здесь требуется восстановление исходной строки (допустима потеря запятых и прочих «слабозначащих» символов).

4.2. Критерии, которые актуальны для данной задачи


4.3. Идея решения

В отличие от предыдущих способов здесь, кроме банальной таблицы транслитерации (приведённой чуть ниже) использовано некоторое алгоритмически-изобретательское решение, идею которого мы сейчас осветим.

Идея решения заключается в подходе к преобразуемой строке как к чередующейся последовательности кириллических и английских «подстрок»:

ThisIsРусскийName/ДляВас/ДемонстрацияOfSwitching


Очевидно, что каждая чётная подстрока в этом случае — точно «кириллическая», а каждая нечётная — «англоязычная». Из способа деления на подстроки следует, что в «кириллической» не встречаются буквы a-zA-Z.

Если теперь мы вставим в строку «разграничители» подстрок, то смело можем перевести все «кириллические» строки в алфавит a-z с помощью любого взаимно-однозначного преобразования, например, ГОСТ.

Наш пример тогда будет выглядеть так:

ThisIs+Russkijj+Name/+DljaVas+/+Demonstracija+OfSwitching


Осталось решить вопрос с теми заглавными русскими буквами, что после транслитерации занимают более одного символа — мы их переводим как ЖZh, потому что так «читабельнее». Кроме того, есть некоторый нюанс с твёрдыми и мягкими знаками, пробелом и «экранированием» плюса. Все эти нюансы освещены в сводных таблицах, приведённых ниже.

4.4. Решение

Решение реализовано на двух языках программирования (PHP и JavaScript), содержится в открытом проекте Translit.
Метод называется BiDiTranslit().

5. Важное примечание

Все функции/способы транслитерации должны уметь (и умеют) работать в двух режимах:


Это необходимо для двух разных способов их использования: а) генерирования «имён папок» в виртуальном «дереве сайта», б) генерирования полных адресов/путей (как это делает WackoWiki или НПЖ).

6. Сводные таблицы

Все правила, по которым производится транслитерация URL-адресов, вынесены нами в отдельный документ сводные таблицы правил транслитерации, чтобы не затруднять чтение статьи.

7. Авторы и благодарности

Материал для этой статьи подготовлен Романом Ивановым и  Кусо Мендокуси.

Библиотеки translit.php и translit.js написаны Романом Ивановым и  Кусо Мендокуси соответственно и отлажены коллективным разумом. Test suite для обеих библиотек подобран коллективным разумом, а организован Романом Ивановым.

Текст этой статьи написан Кусо Мендокуси, стёрт Кусо Мендокуси, заботливо сохранён Романом Ивановым, восстановлен и переписан заново Кусо Мендокуси и бережно вычитан Романом Ивановым.

Мы очень благодарны нам за весь этот цирк.<br />
Ещё мы благодарны всем, спрашивавшим нас о «взаимно-однозначном транслите».

8. Ссылки



 
Один файл. [Показать файлы/форму]
Комментариев нет. [Показать комментарии/форму]
Поделиться ссылкой