более умная замена символов с использованием ruby ​​gsub и regexp

Я пытаюсь создать поведение, подобное постоянной ссылке, для некоторых заголовков статей, и я не хочу добавлять новое поле базы данных для постоянной ссылки. Поэтому я решил написать помощник, который будет преобразовывать название моей статьи из:

"O "focoasă" a pornit cruciada, împotriva bărbaţilor zgârciţi" to "o-focoasa-a-pornit-cruciada-impotriva-barbatilor-zgarciti".

Пока я выяснил, как заменить пробелы дефисами и удалить другие специальные символы (кроме -), используя:

title.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase

Мне интересно, есть ли другой способ заменить символ конкретным другим символом только из одного вызова метода .gsub, поэтому мне не придется связывать методы title.gsub("ă", "a") для всех Спецсимволы UTF-8 моей локализации.

Я думал создать хэш со всеми специальными символами и их аналогами, но я еще не понял, как использовать переменные с регулярными выражениями.

Я искал что-то вроде:

title.gsub(/\s/, "-").gsub(*replace character goes here*).gsub(/[^\w-]/, '').downcase

Спасибо!


person alex.g    schedule 20.04.2010    source источник


Ответы (2)


Я решил эту проблему в своем приложении, используя гем Unidecoder:

require 'unidecode'

def uninternationalize(str)
  Unidecoder.decode(str).gsub("[?]", "").gsub(/`/, "'").strip
end
person Daniel Vandersluis    schedule 20.04.2010
comment
Привет и спасибо за ответ! после установки драгоценного камня я не смог заставить его работать с требованием «unicode», поэтому я добавил config.gem «unidecode», :version =› '~› 1.0.0', :source =› 'rubyforge.org' в файл моей среды. Затем в помощнике я просто создал метод, и все! def permalink(title) Unidecoder.decode(title).gsub(/\s/, -).gsub(/[^\w-]/, '').downcase end - person alex.g; 21.04.2010
comment
Если бы вы пытались потребовать «юникод», это была бы ваша проблема, драгоценный камень — «уникод»;) - person Daniel Vandersluis; 21.04.2010
comment
Проклятие! ты прав :) Вот что я получаю за то, что работаю так поздно. Спасибо еще раз! - person alex.g; 21.04.2010

Если вы хотите транслитерировать только один символ в другой, вы можете использовать метод String#tr, который делает то же самое, что и команда Unix tr: заменяет каждый символ в первом списке символом в той же позиции во втором списке:

'Ünicöde'.tr('ÄäÖöÜüß', 'AaOoUus') # => "Unicode"

Однако я согласен с @Daniel Vandersluis: вероятно, было бы неплохо использовать какую-то более специализированную библиотеку. Подобные вещи могут стать очень утомительными и очень быстрыми. Кроме того, многие из этих символов на самом деле имеют стандартизированную транслитерацию (ä ae, ö oe, ..., ß ss), и пользователи могут ожидать, что транслитерация будет правильной (мне определенно не нравится, когда меня называют Йоргом, если вы действительно должен, вы можете называть меня Йоргом, но я предпочитаю Йорга) и если у вас есть библиотека, которая предоставляет вам эти транслитерации, почему бы не использовать их? Обратите внимание, что есть много транслитераций, которые не являются отдельными символами и, следовательно, не могут использоваться с String#tr в любом случае.

person Jörg W Mittag    schedule 20.04.2010