# 用户名中的感叹号和特殊字符

**URL:** <https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521>\
**Category:** Migration\
**Created:** [2022年十二月2日 16:47 UTC](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521 "2022-12-02T16:47:29Z")\
**Posts on this page:** 6\
**Page:** 2

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2024年四月20日 15:18 UTC](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521/25 "2024-04-20T15:18:56Z")

</div>

> [@Roi](#):
>
> 它还不是现在可能存在的问题。

唯一的问题是您是否对脚本选择的用户名不满意。所以，如果您不介意发生类似这样的情况：

- `clan|nickname` → clan\_nickname
- `[clan]nickname` → clan\_nickname2

那么您可能就没问题了，而且我认为同一个氏族里不太可能出现两个人拥有相同的昵称但带有不同的附加字符，所以我觉得您可能就没问题了。

---

<div class="post-metadata">

**Author:** ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)\
**Post date:** [2024年四月22日 14:38 UTC](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521/26 "2024-04-22T14:38:14Z")

</div>

不幸的是，我们最终不得不自己编写整个迁移脚本。当时（2022 年底）可用的脚本绝对还没有达到“完成”状态。引用的代码片段缺失，其他的代码完全没有意义。

我们处理的部分包括重命名不符合 discourse 标准的用户名。我们有超过 10k 用户，所以我们只是将用户名分配给没有此类限制的“user name”字段，并且当用户名违反任何规则时，我们将其更改为用户名的 md5 字符串。然后，我们给用户一个月的时间自由更改他们的用户名，以便他们可以将其改回类似于原始用户名的名称。

这是代码摘录：

```plaintext
    public static string ParseName(string text)
    {
        var reservedName = new string[] { "user", "system", "moderators" };
        var result = NormalizeText(text);

        // If reserved change it
        if (reservedName.Contains(result, StringComparer.OrdinalIgnoreCase))
            result = text.ToLower().ToMD5();

        // Invalid alphanumeric
        else if (!Regex.IsMatch(result, @”^[a-zA-Z0-9_.-]*$”))
            result = text.ToLower().ToMD5();

        // Invalid repeated
        else if (Regex.IsMatch(result, @”[-_.]{2,}”))
            result = text.ToLower().ToMD5();

        // Invalid trailing char
        else if (Regex.IsMatch(result, @”/[\\p{L}\\p{N}]+$”))
            result = text.ToLower().ToMD5();

        // Confusing extensions
        else if (Regex.IsMatch(result, @”/\\.(js|json|css|htm|html|xml|jpg|jpeg|png|gif|bmp|ico|tif|tiff|woff)$/i”))
            result = text.ToLower().ToMD5();

        // Starting and ending dots
        else if (result.StartsWith(".") || result.EndsWith("."))
            result = text.ToLower().ToMD5();

        // No more than 60 character
        result = result.Truncate(60);

        return result;
    }

```

我们使用此文件作为参考来确定什么是限制。可能已经更改了，所以请留意。

> <https://github.com/discourse/discourse/blob/main/app/models/username_validator.rb>

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2024年四月22日 18:19 UTC](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521/27 "2024-04-22T18:19:10Z")

</div>

> [@Crius](#):
>
> ，我们最终不得不自己创建整个迁移脚本。

你是基于现有的导入脚本做的吗？如果那样的话，它会调用 [discourse/lib/user\_name\_suggester.rb at main · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/main/lib/user_name_suggester.rb) 并且就能正常工作。

---

<div class="post-metadata">

**Author:** ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)\
**Post date:** [2024年四月23日 00:00 UTC](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521/28 "2024-04-23T00:00:29Z")

</div>

我们已经放弃了该脚本，因为它处理拥有 1000 万条回复的论坛速度非常慢。

我们用 C# 从头开始创建了所有内容。迁移所有内容（不包括头像）并创建重定向以匹配不同的 URL 格式大约花费了 4-5 小时。脚本的第二次运行，使用特定参数，还将通过扫描回复并查找旧 URL 格式来更新过去 6 个月内每个活跃用户的头像并添加所有必要的重定向。

这花费了大约几天时间，但这是可以后台进行的事情，因为对我们来说最重要的是在不到一天的时间内让论坛运行起来并包含所有内容。

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2024年四月23日 00:19 UTC](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521/29 "2024-04-23T00:19:35Z")

</div>

干得好！这真的很酷。

供参考，现有脚本会跳过已存在的内容，因此最终导入可能不到一个小时就能完成，特别是如果你告诉它最近导入的数据的日期。不过，第一次运行会非常痛苦。

---

<div class="post-metadata">

**Author:** ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)\
**Post date:** [2024年四月30日 14:18 UTC](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521/30 "2024-04-30T14:18:07Z")

</div>

是的，我知道它也恢复了，但一些旧内容非常混乱（论坛在 2000 年初进行了迁移），导致脚本大部分时间都失败或很快变得非常缓慢。

相信我，如果我们能避免 3 个月的编写和测试，我们早就这么做了！😃

[上一頁](https://meta.discourse.org/t/exclamation-mark-and-special-characters-in-usernames/247521.md?page=1)
