You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言基于正则生成首字母缩写的特殊字符匹配问题

Go版本
go version go1.16.7 linux/amd64
问题描述

我正在完成生成首字母缩写的练习,选择用正则表达式实现。给出的测试用例如下:

input:    "Ruby on Rails",
    expected: "ROR"
    
    input:    "GNU Image Manipulation Program",
    expected: "GIMP"

    input:    "Complementary metal-oxide semiconductor",
    expected: "CMOS"

    input:    "Something - I made up from thin air",
    expected: "SIMUFTA"

    input:    "Halley's Comet",
    expected: "HC"

    input:    "The Road _Not_ Taken",
    expected: "TRNT"

当前编写的代码可通过大部分简单测试,提取单词首字母生成缩写,例如Portable Network Graphics -> PNG,代码如下:

代码实现

// Package acronym creates an acronym based on Capitalized Letters
package acronym

import (
    "regexp"
    "strings"
)

// Abbreviate: creates an acronym for a full form string
func Abbreviate(s string) string {
    re := regexp.MustCompile(`\b[A-Za-z]`)
    abbreviation := strings.Join(re.FindAllString(s, -1), "")
    return strings.ToUpper(abbreviation)
}

当前仅两个测试用例不通过:

=== RUN   TestAcronym
    acronym_test.go:11: Acronym test [Halley's Comet], expected [HC], actual [HSC]
    acronym_test.go:11: Acronym test [The Road _Not_ Taken], expected [TRNT], actual [TRT]
--- FAIL: TestAcronym (0.00s)
待解决问题

我不清楚如何调整正则,才能让Halley's Comet返回HC,同时匹配到The Road _Not_ Taken中的N。我保留小写字母[a-z]匹配是为了适配小写开头单词的测试用例,不想使用提前删除特殊字符的hack方案降低通用性,请问要怎么处理'、_这类字符,让缩写生成函数更鲁棒?


解决方案

问题原因

原正则使用的原生\b单词边界规则不符合需求:

  • 原生单词边界的判定逻辑为「单词字符(a-z、A-Z、0-9、_)与非单词字符的交界」,'属于非单词字符,因此Halley's中'和s的交界会被判定为单词边界,导致多匹配到s得到错误结果HSC
  • 下划线_属于原生单词字符范畴,因此_Not_中_和N的交界不会被判定为单词边界,导致漏匹配N得到错误结果TRT

调整后代码

// Package acronym creates an acronym based on Capitalized Letters
package acronym

import (
    "regexp"
    "strings"
)

// Abbreviate: creates an acronym for a full form string
func Abbreviate(s string) string {
    // 正则逻辑:匹配字符串开头/非字母+非单引号 后的第一个英文字母
    re := regexp.MustCompile(`(?:^|[^a-zA-Z'])([a-zA-Z])`)
    matches := re.FindAllStringSubmatch(s, -1)
    var abbreviation strings.Builder
    for _, match := range matches {
        abbreviation.WriteString(match[1])
    }
    return strings.ToUpper(abbreviation.String())
}

逻辑说明

  1. 用非捕获组(?:^|[^a-zA-Z'])定义首字母的前置规则:要么是字符串开头,要么前一个字符既不是英文字母也不是单引号,保证单引号连接的内容不会被拆分为多个单词
  2. 用捕获组提取符合条件的英文字母,过滤掉前置的非字母字符
  3. 拼接所有捕获到的首字母后转大写,兼容小写开头的单词场景,无需额外预处理特殊字符

内容的提问来源于stack exchange,提问作者user4851126

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 14:39:03