Coding problem · Easy · Language Idioms

Slugify a Title (Strings & Regex)

Easy Language practicals Seen at Automattic, Laravel shops, Agencies

Write slugify(string $title, int $maxLength): string for blog URLs:

  • lowercase the title;
  • replace every run of characters other than a–z and 0–9 with a single -;
  • trim leading/trailing -;
  • if the slug is longer than $maxLength, shorten it without cutting a word in half: cut at the last - within the limit. If the first word alone is longer than the limit, hard-cut it.

Input is ASCII.

Example 1

Input: title = "PHP 8.3: What's New?", maxLength = 50
Output: "php-8-3-what-s-new"

Example 2

Input: title = "Laravel queues and Horizon in production", maxLength = 20
Output: "laravel-queues-and"

Hints

Hint 1

preg_replace('/[^a-z0-9]+/', '-', strtolower($title)) does most of the work.

Hint 2

Check whether the character right after the cut is - before searching backwards with strrpos.

Write and run your solution

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the solution

Time O(n) · Space O(n)

A single preg_replace with a character-class negation and + collapses every run of separators into one dash, and trim($s, '-') removes them from the ends. For truncation: if the cut lands inside a word (the next character isn't a dash), back up to the last dash with strrpos.

For real-world, non-ASCII titles use Str::slug() in Laravel or transliterator_transliterate('Any-Latin; Latin-ASCII', ...) from the intl extension before the regex.

Reference solution

<?php

function slugify(string $title, int $maxLength): string
{
    $slug = trim(preg_replace('/[^a-z0-9]+/', '-', strtolower($title)), '-');
    if (strlen($slug) <= $maxLength) {
        return $slug;
    }
    $cut = substr($slug, 0, $maxLength);
    if ($slug[$maxLength] !== '-' && ($dash = strrpos($cut, '-')) !== false) {
        $cut = substr($cut, 0, $dash);
    }
    return rtrim($cut, '-');
}

Common mistakes

  • Producing -- sequences by replacing each character individually.
  • Cutting mid-word.
  • Forgetting multibyte input in production (use mb_* or intl).

Follow-up questions

  • Ensure slugs are unique in the database (append -2, -3...).
  • Support Unicode titles.