php / regex: "linkify" заголовки блога

Я пытаюсь написать простую функцию PHP, которая может принимать строку типа

Topic: Some stuff, Maybe some more, it's my stuff?

и вернуться

topic-some-stuff-maybe-some-more-its-my-stuff

Как таковой:

  • в нижнем регистре
  • удалить все символы, не содержащие алфавитно-цифровые символы
  • заменить все пробелы (или группы пространств) на дефисы

Могу ли я сделать это с помощью одного регулярного выражения?

Related of "php / regex: "linkify" заголовки блога"

Многие структуры предоставляют функции для этого

CodeIgniter: http://bitbucket.org/ellislab/codeigniter/src/c39315f13a76/system/helpers/url_helper.php#cl-472

wordpress (имеет еще много кода): http://core.trac.wordpress.org/browser/trunk/wp-includes/formatting.php#L814

 function Slug($string) { return strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([az]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8')), '-')); } $topic = 'Iñtërnâtiônàlizætiøn'; echo Slug($topic); // internationalizaetion $topic = 'Topic: Some stuff, Maybe some more, it\'s my stuff?'; echo Slug($topic); // topic-some-stuff-maybe-some-more-it-s-my-stuff $topic = 'here عربي‎ Arabi'; echo Slug($topic); // here-arabi $topic = 'here 日本語 Japanese'; echo Slug($topic); // here-japanese 

Вы можете сделать это с помощью одного preg_replace :

 preg_replace(array("/[AZ]/e", "/\\p{P}/", "/\\s+/"), array('strtolower("$0")', '', '-'), $str); 

Технически вы можете сделать это с помощью одного регулярного выражения, но это проще.

Упреждающий ответ: да, он неоправданно использует регулярные выражения (хотя и очень простые), неоправданно большое количество вызовов strtolower , и он не учитывает неанглийские символы (он даже не дает кодировки); Я просто удовлетворяю требованиям OP.

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

 $str = "Topic: Some stuff, Maybe some more, it's my stuff?"; $str = implode('-',str_word_count(strtolower($str),2)); echo $str; 

Не пройдя весь маршрут UTF-8:

 $str = "Topic: Some stuff, Maybe some more, it's my Iñtërnâtiônàlizætiøn stuff?"; $str = implode('-',str_word_count(strtolower(str_replace("'","",$str)),2,'Þßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ')); echo $str; 

дает

тема-некоторые-вещи-возможно-несколько больше-его-моя-iñtërnâtiônàlizætiøn-материал