Slug 生成器
将任意文本转换为简洁的 URL 友好型 Slug
输入文本
Slug
什么是 URL Slug?
URL Slug 是网址中用于以人类可读形式标识特定页面的部分。在 URL https://example.com/blog/my-first-post 中,Slug 即为 my-first-post。Slug 生成器将页面标题或描述转换为只包含小写字母、数字和连字符(或其他选定分隔符)的字符串。这一过程会移除空格、去除重音符号和变音标记、删除特殊字符,并将连续空白压缩为单个分隔符。
Slug 生成是内容管理系统、静态站点生成器、博客平台以及任何从用户输入衍生 URL 的应用程序的标准步骤。WordPress、Ghost、Hugo、Next.js 和 Django 均内置了 Slug 生成逻辑,因为可读的 URL 既能提升可用性,也有助于搜索引擎优化。一个格式规范的 Slug 能让用户在点击链接之前就了解页面内容。
"slug" 一词来源于报纸出版业,指在生产流程中用于标识稿件的简短标签。在 Web 开发中,Slug 承担着相同的功能:它是从较长标题或名称派生出的紧凑、唯一、URL 安全的标识符。由于 Slug 是通过程序化方式生成的,可靠的 Slug 生成器能确保每个页面和每种语言版本的一致性。
为什么使用这个 Slug 生成器?
手动创建 URL Slug 容易出错。忘记去除重音符号、留下双连字符,或未能处理 Unicode 输入的边界情况,都会产生损坏或难看的 URL。本工具自动处理这些问题。
Slug 生成器使用场景
Slug 生成规则与字符处理
Slug 生成遵循一系列可预测的转换步骤。理解每个步骤有助于调试意外输出,或自行构建 slugify 函数。
- 1. Unicode 规范化(NFD)将组合字符分解为基础字符加组合标记。例如,é(U+00E9)分解为 e 加组合锐音符(U+0301)。这使得变音标记可在下一步中被移除。
- 2. 去除变音标记移除 Unicode 组合变音标记块(U+0300–U+036F)中的所有字符。此步骤完成后,café 变为 cafe,Ñ 变为 N。
- 3. 移除特殊字符将所有非字母、非数字、非空白、非连字符的字符替换为空格。这会删除标点符号、符号以及没有 ASCII 对应形式的字符。
- 4. 修剪并压缩空白移除首尾空白,然后将连续的空格、下划线或连字符压缩为单个选定的分隔符。
- 5. 应用大小写与分隔符可选择转换为小写,并使用选定的分隔符连接各词:连字符(-)、下划线(_)或点号(.)。
字符转换参考表
下表展示了 Slug 生成过程中常见字符的处理方式:
| 输入 | 输出 | 应用规则 |
|---|---|---|
| Hello World | hello-world | Lowercase + space → hyphen |
| Café au Lait | cafe-au-lait | NFD normalization strips é → e |
| naïve résumé | naive-resume | Multiple diacritics removed |
| Price: $9.99! | price-9-99 | Symbols ($, !, :) removed |
| too many | too-many | Whitespace trimmed and collapsed |
| one--two___three | one-two-three | Mixed separators collapsed |
| Привет мир | privet-mir | Cyrillic (if transliteration) or removed |
| file_name.txt | file-name-txt | Dots and underscores replaced |
| React & Vue | react-vue | Ampersand removed |
| 2026-03-30 | 2026-03-30 | Digits and hyphens preserved |
代码示例
以下展示在常见编程语言和框架中生成 Slug 的方法。每个示例均处理 Unicode 规范化、变音标记移除和分隔符插入。
function slugify(text, separator = '-') {
return text
.normalize('NFD') // decompose accented chars
.replace(/[\u0300-\u036f]/g, '') // strip diacritics
.toLowerCase()
.replace(/[^\w\s-]/g, ' ') // drop special chars
.trim()
.replace(/[\s_-]+/g, separator) // collapse whitespace → separator
// slugify('Café au Lait') → "cafe-au-lait"
// slugify('Hello World', '_') → "hello_world"
}
// Node.js alternative using the `slugify` npm package:
// npm install slugify
// const slugify = require('slugify')
// slugify('Hello World', { lower: true, strict: true }) → "hello-world"import re
import unicodedata
def slugify(text: str, separator: str = '-') -> str:
"""Convert text to a URL-safe slug."""
text = unicodedata.normalize('NFD', text)
text = text.encode('ascii', 'ignore').decode('ascii') # strip non-ASCII
text = text.lower()
text = re.sub(r'[^\w\s-]', ' ', text)
text = text.strip()
text = re.sub(r'[\s_-]+', separator, text)
return text
# slugify('Café au Lait') → "cafe-au-lait"
# slugify('Hello World', '_') → "hello_world"
# Alternative: python-slugify (pip install python-slugify)
# from slugify import slugify
# slugify('Café au Lait') → "cafe-au-lait"package main
import (
"regexp"
"strings"
"unicode"
"golang.org/x/text/unicode/norm"
"golang.org/x/text/transform"
"golang.org/x/text/runes"
)
func slugify(text string) string {
// NFD normalize and strip diacritics
t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
result, _, _ := transform.String(t, text)
result = strings.ToLower(result)
re := regexp.MustCompile(`[^\w\s-]+`)
result = re.ReplaceAllString(result, " ")
result = strings.TrimSpace(result)
re = regexp.MustCompile(`[\s_-]+`)
result = re.ReplaceAllString(result, "-")
return result
}
// slugify("Café au Lait") → "cafe-au-lait"
// slugify("Hello World") → "hello-world"function slugify(string $text, string $separator = '-'): string {
// Transliterate non-ASCII characters
$text = transliterator_transliterate(
'Any-Latin; Latin-ASCII; Lower()', $text
);
// Remove anything that is not a word char, space, or hyphen
$text = preg_replace('/[^\w\s-]/', ' ', $text);
$text = trim($text);
$text = preg_replace('/[\s_-]+/', $separator, $text);
return $text;
}
// slugify('Café au Lait') → "cafe-au-lait"
// slugify('Hello World', '_') → "hello_world"