Headline to URL slug
A blog engine builds the address of each post from its headline. Convert the headline to a slug: lowercase everything, replace every run of characters that are not a-z or 0-9 with a single hyphen, and remove any hyphens left at the start or the end. If nothing remains, print untitled.
Input
One line: the headline, 0 to 200 printable ASCII characters. The line may be empty.
Output
One line: the slug, or untitled when the headline contains no letters or digits.
Example 1
Input
Ten Ways to Brew Better Coffee
Output
ten-ways-to-brew-better-coffee
Lowercased; each space becomes a hyphen.
Example 2
Input
PHP 8.4 released: what's new?
Output
php-8-4-released-what-s-new
The dot, the colon plus space, the apostrophe and the question mark are all non-alphanumeric runs. The trailing ? would leave a hyphen at the end, which is trimmed.
Example 3
Input
---
Output
untitled
Only hyphens, so nothing survives trimming and the fallback is printed.
Constraints
- 0 <= length <= 200
- Printable ASCII only
Hints
Hint 1 of 3
strtolower() first; then think of the rest as one replacement over the whole string.
Hint 2 of 3
preg_replace('/[^a-z0-9]+/', '-', $s) replaces every run of unwanted characters with one hyphen; the + is what collapses runs.
Hint 3 of 3
trim($s, '-') strips hyphens from both ends, and a final === '' check chooses the fallback.
Solution
Show a reference solution and explanation
<?php
$line = fgets(STDIN);
$headline = $line === false ? '' : trim($line);
$slug = strtolower($headline);
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
$slug = trim($slug, '-');
if ($slug === '') {
$slug = 'untitled';
}
echo $slug, "\n";
Why it works
A regular expression is the right tool because the rule is about runs of characters, not single ones. The character class [^a-z0-9] matches anything that is not a lowercase letter or a digit, and the + quantifier makes one match cover a whole run, so a comma followed by three spaces becomes one hyphen rather than four. trim() with a second argument strips a chosen character set from the ends instead of whitespace. The empty headline is the edge case: fgets returns false when there is no input at all, so the solution checks for that before trimming, and after all replacements an empty string triggers the untitled fallback.
Lesson for this exercise: Strings in PHP