Go语言实现SEO友好的Slug生成器:支持中英文、唯一性检查

在 Web 开发中,Slug 是 URL 中的友好标识符,通常用于文章、分类或页面的路径,比如:

arduino 复制代码
https://example.com/blog/go-slug-generator

在 Go 语言的 Web 项目中,Slug 生成器需要满足以下需求:

  1. 支持中英文:中文转换为拼音,英文保持不变。
  2. 去除特殊字符 :仅保留字母、数字和 -(连字符)。
  3. 确保唯一性 :如果数据库中已存在相同的 Slug,则自动添加递增后缀(如 example, example-1)。

本文将带你一步步实现这个功能!🔥


1. Slug 生成器的实现

(1) 代码示例

go 复制代码
package utils

import (
	"dagicms-server/global"
	"fmt"
	"github.com/mozillazg/go-pinyin"
	"regexp"
	"strings"
)

// GenerateSlug 生成 SEO 友好的 slug(支持中英文,去除特殊字符,确保唯一性)
func GenerateSlug(title string, tableName string, id uint) string {
	// 1. 处理标题,转换中文为拼音,并保留英文
	baseSlug := ConvertToSlug(title)

	// 2. 只保留字母、数字、空格和连字符
	reg := regexp.MustCompile(`[^a-zA-Z0-9\s-]`)
	baseSlug = reg.ReplaceAllString(baseSlug, "")

	// 3. 替换空格为连字符
	baseSlug = strings.ReplaceAll(baseSlug, " ", "-")

	// 4. 处理连字符,去除多余的 `--`
	baseSlug = cleanHyphens(baseSlug)

	// 5. 如果转换后的 slug 为空,设置默认值
	if baseSlug == "" {
		baseSlug = "untitled"
	}

	// 6. 检查数据库,确保 slug 唯一
	finalSlug := baseSlug
	counter := 1
	for {
		var exists bool
		query := fmt.Sprintf("SELECT EXISTS(SELECT 1 FROM %s WHERE slug = ? AND id != ?)", tableName)
		global.GVA_DB.Raw(query, finalSlug, id).Scan(&exists)

		if !exists {
			break
		}
		// 若已存在,添加递增数字后缀
		finalSlug = fmt.Sprintf("%s-%d", baseSlug, counter)
		counter++
	}

	return finalSlug
}

// ConvertToSlug 处理中英文,转换中文为拼音,英文保留
func ConvertToSlug(input string) string {
	var result []string
	for _, r := range input {
		if isChinese(r) {
			// 将中文字符转换为拼音
			pinyinArgs := pinyin.NewArgs()
			pinyinList := pinyin.LazyPinyin(string(r), pinyinArgs)
			if len(pinyinList) > 0 {
				result = append(result, pinyinList[0]) // 取拼音
			}
		} else {
			result = append(result, string(r)) // 直接保留英文
		}
	}
	return strings.Join(result, "")
}

// isChinese 判断字符是否为中文
func isChinese(r rune) bool {
	return r >= 0x4E00 && r <= 0x9FA5
}

// cleanHyphens 处理连字符,避免 "--" 出现
func cleanHyphens(input string) string {
	for strings.Contains(input, "--") {
		input = strings.ReplaceAll(input, "--", "-")
	}
	return strings.Trim(input, "-")
}

2. 代码解析

(1) 处理标题,确保 SEO 友好

css 复制代码
baseSlug := ConvertToSlug(title)
  • 该函数会将 中文转换为拼音,保留英文字符。

  • 例如:

    scss 复制代码
    ConvertToSlug("Go 语言编程")  // 结果: "Go-yu-yan-bian-cheng"
    ConvertToSlug("Hello 世界")  // 结果: "Hello-shi-jie"

(2) 过滤特殊字符

ini 复制代码
reg := regexp.MustCompile(`[^a-zA-Z0-9\s-]`)
baseSlug = reg.ReplaceAllString(baseSlug, "")
  • 该正则表达式确保只保留:大小写字母、数字、空格、连字符 -

(3) 处理空格,确保 URL 友好

ini 复制代码
baseSlug = strings.ReplaceAll(baseSlug, " ", "-")
  • 将所有空格替换为 -,避免出现 %20 这样的 URL 编码问题。

(4) 避免 -- 连字符问题

ini 复制代码
baseSlug = cleanHyphens(baseSlug)
  • 该函数确保不会出现 --,如 "hello--world" 会变成 "hello-world"

(5) 数据库检查,确保唯一性

perl 复制代码
query := fmt.Sprintf("SELECT EXISTS(SELECT 1 FROM %s WHERE slug = ? AND id != ?)", tableName)
global.GVA_DB.Raw(query, finalSlug, id).Scan(&exists)

if exists {
    finalSlug = fmt.Sprintf("%s-%d", baseSlug, counter)
}
  • 若数据库已存在相同的 Slug,则自动添加数字后缀,确保唯一性:

    复制代码
    example → example-1 → example-2

3. 代码示例

Go 项目 中使用这个 Slug 生成器:

go 复制代码
package main

import (
	"fmt"
	"your_project/utils"
)

func main() {
	title1 := "Go 语言编程"
	title2 := "Hello 世界"
	title3 := "Golang URL 生成"

	slug1 := utils.GenerateSlug(title1, "articles", 1)
	slug2 := utils.GenerateSlug(title2, "articles", 2)
	slug3 := utils.GenerateSlug(title3, "articles", 3)

	fmt.Println(slug1) // 输出: go-yu-yan-bian-cheng
	fmt.Println(slug2) // 输出: hello-shi-jie
	fmt.Println(slug3) // 输出: golang-url-sheng-cheng
}

4. 总结

支持中英文 :中文转换拼音,英文保持原样

去除特殊字符 :仅保留字母、数字和 -

避免 -- 问题 :确保 slug 规范

唯一性检查:避免数据库冲突

🚀 这样,我们就实现了一个 SEO 友好的 Slug 生成器 ,并且可以轻松集成到 Django / Go Web 项目 中!

👉 如果觉得有用,请点赞 👍 或者分享你的改进建议! 🚀

相关推荐
Luo_LA4 小时前
【排序算法对比】快速排序、归并排序、堆排序
java·算法·排序算法
一只韩非子5 小时前
一句话告诉你什么叫编程语言自举!
前端·javascript·后端
沈二到不行5 小时前
多头注意力&位置编码:完型填空任务
人工智能·后端·deepseek
追逐时光者5 小时前
C# 中比较实用的关键字,基础高频面试题!
后端·c#·.net
GoGeekBaird5 小时前
一文搞懂:Anthropic发布MCP重要更新,告别长连接
后端·操作系统
Asthenia04126 小时前
面试问题分析:为什么Java能实现反射机制,其他语言不行?
后端
拳布离手6 小时前
fastgpt工作流探索
后端
Asthenia04126 小时前
IO 多路复用详解:从概念->系统调用-> Java 在NIO中实现
后端
Asthenia04126 小时前
场景题-Java 单体项目优化:应对高并发客户端访问的性能与线程安全分析
后端
安然无虞6 小时前
31天Python入门——第5天:循环那些事儿
开发语言·后端·python