Как убрать диакритические знаки из текста?

Я делаю веб-сайт на шведском языке, а шведские буквы — это å, ä и ö.

Мне нужно, чтобы строка, введенная пользователем, стала безопасной для URL с PHP.

В принципе, нужно преобразовать все символы в подчеркивание, все, КРОМЕ этих:

 A-Z, a-z, 1-9

и все шведские должны быть преобразованы следующим образом:

«å» на «a» и «ä» на «a» и «ö» на «o» (просто удалите точки выше).

Остальные должны стать символами подчеркивания, как я уже сказал.

Я плохо разбираюсь в регулярных выражениях, поэтому буду признателен за помощь, ребята!

Спасибо

ПРИМЕЧАНИЕ: НЕ URLENCODE... Мне нужно сохранить его в базе данных... и т.д., и т.д., urlencode у меня не работает.


person Community    schedule 20.11.2009    source источник


Ответы (9)


Это должно быть полезно, которое обрабатывает почти все случаи.

function Unaccent($string)
{
    return preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml|caron);~i', '$1', htmlentities($string, ENT_COMPAT, 'UTF-8'));
}
person user1518659    schedule 12.10.2012
comment
Это выглядит потрясающе, но есть проблемы, например, с греческими символами. - person nico gawenda; 11.04.2013
comment
Это самое элегантное и творческое решение этой проблемы, которое я нашел... Поздравляю! - person jacmkno; 23.02.2018
comment
К сожалению, это не работает с ř, ž, ť, ň, ů, ě, č, ď (чешский) - person F. Korf; 31.01.2021

Используйте iconv для преобразования строк из заданной кодировки в ASCII, а затем замените не -буквенно-цифровые символы с использованием preg_replace:

$input = 'räksmörgås och köttbullar'; // UTF8 encoded
$input = iconv('UTF-8', 'ASCII//TRANSLIT', $input);
$input = preg_replace('/[^a-zA-Z0-9]/', '_', $input);
echo $input;

Результат:

raksmorgas_och_kottbullar
person Pär Wieslander    schedule 20.11.2009
comment
Вы должны использовать UTF-8 следующим образом: $data = iconv('UTF-8', 'ASCII//TRANSLIT', $data); - в противном случае вы можете столкнуться с этим уведомлением: Неправильный набор символов, преобразование из UTF8' to ASCII//TRANSLIT' не разрешено - person Hirnhamster; 06.11.2012
comment
Пожалуйста, обновите свой ответ, включив в него предложение @Hirnhamster. Ваш отсутствующий дефис в «UTF-8» влияет на других людей. - person Timo; 11.03.2014

и все шведские должны быть преобразованы следующим образом:

«å» на «a» и «ä» на «a» и «ö» на «o» (просто удалите точки выше).

Используйте normalizer_normalize(), чтобы избавиться от диакритические знаки.

Остальные должны стать символами подчеркивания, как я уже сказал.

Используйте preg_replace() с шаблоном [\W] (iow: любой символ, который не t соответствуют буквам, цифрам или знаку подчеркивания), чтобы заменить их символами подчеркивания.

Окончательный результат должен выглядеть так:

$data = preg_replace('[\W]', '_', normalizer_normalize($data));
person BalusC    schedule 20.11.2009

Если расширение intl php включено, вы можете использовать транслитератор следующим образом:

protected function removeDiacritics($string)
{
    $transliterator = \Transliterator::create('NFD; [:Nonspacing Mark:] Remove; NFC;');
    return $transliterator->transliterate($string);
}

Чтобы удалить другие специальные символы (не только диакритические знаки, такие как «æ»)

protected function removeDiacritics($string)
{
    $transliterator = \Transliterator::createFromRules(
        ':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;',
        \Transliterator::FORWARD
    );
    return $transliterator->transliterate($string);
}
person dryobs    schedule 13.11.2017
comment
Это должен быть принятый ответ. - person Bernhard Schussek; 15.03.2021

Если вы просто заинтересованы в том, чтобы обеспечить безопасность URL-адресов, вам нужен urlencode.

Возвращает строку, в которой все не буквенно-цифровые символы, кроме -_. были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры и пробелы, закодированные как знаки плюс (+). Он кодируется так же, как кодируются отправленные данные из формы WWW, то есть так же, как в медиа-типе application/x-www-form-urlencoded. Это отличается от кодировки » RFC 1738 (см. rawurlencode()) тем, что по историческим причинам пробелы кодируются знаком плюс (+).

Если вы действительно хотите удалить все, кроме A-Z, a-z, 1-9 (кстати, что не так с 0?), то вы хотите:

$mynewstring = preg_replace('/[^A-Za-z1-9]/', '', $str);
person Dominic Rodger    schedule 20.11.2009
comment
Если вы хотите сделать это безопасным, вам нужен urlencode. Тот факт, что вы хотите сохранить его в базе данных, не имеет значения (кроме того, что вы захотите избежать его для своего запроса на вставку SQL в дополнение к тому, чтобы сделать его безопасным для URL-адресов). - person Quentin; 20.11.2009
comment
Вы просто не понимаете. Он хочет, чтобы его было безопасно использовать в качестве URL-адреса, но не НАСТОЛЬКО безопасно. Он предпочел бы, чтобы он терпел неудачу на пробеле или амперсанде. - person JohnFx; 20.11.2009

так просто как

 $str = str_replace(array('å', 'ä', 'ö'), array('a', 'a', 'o'), $str); 
 $str = preg_replace('/[^a-z0-9]+/', '_', strtolower($str));

предполагая, что вы используете одну и ту же кодировку для своих данных и своего кода.

person user187291    schedule 20.11.2009
comment
'/[^a-z0-9]+/i' или '/[^A-Za-z0-9]+/', чтобы игнорировать регистр - person Salman A; 20.11.2009
comment
strtr удобнее переводить наборы символов, например: $str = strtr($str,aëïöü,aeiou); он не использует массивы - person danii; 20.11.2009
comment
Массивы обременены поддержкой нескольких тысяч символов с диакритическими знаками, известными в человеческом мире. Просто используйте normalizer. - person BalusC; 20.11.2009

Одним из простых решений является использование функции str_replace с поиском и заменой массивов букв. .

person Mihail Dimitrov    schedule 20.11.2009

Вам не нужны причудливые регулярные выражения для фильтрации шведских символов, просто используйте функцию strtr чтобы «перевести» их, например:

$your_URL = "www.mäåö.com";
$good_URL = strtr($your_URL, "äåöë etc...", "aaoe etc...");
echo $good_URL;

-> вывод: www.maao.com :)

person danii    schedule 20.11.2009
comment
Это всего лишь кошмар обслуживания, чтобы покрыть тысячи персонажей, известных в человеческом мире. - person BalusC; 20.11.2009

person    schedule
comment
Обратите внимание, что normalizer_normalize() является частью расширения PHP intl, которое не всегда активно. Это расширение было добавлено в ядро ​​в PHP 5.3, но в большинстве дистрибутивов Linux оно неактивно по умолчанию. Например, в Debian он находится в отдельном пакете php5-intl. Если вы не можете установить/активировать его, попробуйте ext/iconv. вместо - person ; 21.08.2011
comment
@Mytskine Я добавил комментарий. Спасибо, что указали на это: для меня это было по умолчанию, поэтому я не задумывался об этом. - person Jeremy L; 22.12.2011