php / regex: "linkify" заголовки блога - PullRequest
3 голосов
/ 14 июля 2010

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

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

и возврат

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

Как таковой:

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

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

Ответы [ 4 ]

3 голосов
/ 14 июля 2010
function Slug($string)
{
    return strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([a-z]{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
2 голосов
/ 14 июля 2010

Вы можете сделать это с одним preg_replace:

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

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

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

2 голосов
/ 14 июля 2010

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

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

2 голосов
/ 14 июля 2010

Почему регулярные выражения считаются универсальной панацеей от всех жизненных проблем (только потому, что простой обратный след в 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;

дает

topic-some-stuff-Может-еще-его-моя-iñtërnâtiônàlizætiøn-вещи

...