Munib
Munib

Reputation: 3671

Convert text to hyphen-separated string (slug) including other custom replacements

I want to make a hyphen-separated string (for use in the URL) based on the user-submitted title of the post. Suppose if the user entered the title of the post as:

$title = "USA is going to deport indians -- Breaking News / News India";

I want to convert it as below

$slug = usa-is-going-to-deport-indians-breaking-news-news-india";

There could be some more characters that I also want to be converted. For Example '&' to 'and' and '#', '%', to hyphen(-).

One of the ways that I tried was to use the str_replace() function, but with this method I have to call str_replace() too many times and it is time consuming.

One more problem is there could be more than one hyphen (-) in the title string, I want to convert more than one hyphens (-) to one hyphen(-).

Is there any robust and efficient way to solve this problem?

Upvotes: 1

Views: 5662

Answers (3)

mickmackusa
mickmackusa

Reputation: 47934

There are three steps in this task (creating a "slug" string); each requires a separate pass over the input string.

  1. Cast all characters to lowercase.

  2. Replace ampersand symbols with [space]and[space] to ensure that the symbol is not consumed by a later replacement AND the replacement "and" is not prepended or appended to its neighboring words.

  3. Replace sequences of one or more non-alphanumeric characters with a literal hyphen.

Multibyte-safe Code: (Demo)

$title = "ÛŞÃ is going to dèport 80% öf indians&citizens are #concerned -- Breaking News / News India";

echo preg_replace(
         '/[^\pL\pN]+/u',
         '-',
         str_replace(
             '&',
             ' and ',
             mb_strtolower($title)
         )
     );

Output:

ûşã-is-going-to-dèport-80-öf-indians-and-citizens-are-concerned-breaking-news-news-india

Note that the replacement in str_replace() could be done within the preg_replace() call by forming an array of find strings and an array of replacement strings. However, this may be false economy -- although there would be fewer function calls, the more expensive regex-based function call would make two passes over the entire string.

If you wish to convert accented characters to ASCII characters, then perhaps read the different techniques at Convert accented characters to their plain ascii equivalents.

If you aren't worries about multibyte characters, then the simpler version of the same approach would be:

echo preg_replace(
         '/[^a-z\d]+/',
         '-',
         str_replace(
             '&',
             ' and ',
             strtolower($title)
         )
     );

To mop up any leading or trailing hyphens in the result string, it may be a good idea to unconditionally call trim($resultstring, '-'). Demo

For a deeper dive on the subject of creating a slug string, read PHP function to make slug (URL string).

Upvotes: 0

Lars
Lars

Reputation: 11

I would suggest using the sanitize_title() function check the documentation

Upvotes: 1

Dead Man
Dead Man

Reputation: 2921

You can use preg_replace function to do this :

Input :

$string = "USA is going to deport indians -- Breaking News / News India";

$string = preg_replace("/[^\w]+/", "-", $string);
echo strtolower($string);

Output :

usa-is-going-to-deport-indians-breaking-news-news-india

Upvotes: 8

Related Questions