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

如何在Groovy中实现类Excel式字母数字字符串排序?

Groovy实现Excel风格的字母数字排序

Excel的字母数字排序(自然排序)会将字符串中的连续数字视为整体数值比较,而非逐字符的字典序。要在Groovy中实现相同效果,需要自定义比较逻辑,替代默认a <=> b的字典序排序方式。

实现步骤与代码示例

  1. 拆分字符串为字母/数字片段:通过正则表达式将每个字符串拆分为连续的字母段和数字段。
  2. 自定义比较器:逐个对比两个字符串的对应片段,数字按数值比较,字母按字典序(默认不区分大小写,匹配Excel行为),字母段优先于数字段。

完整代码:

// 将字符串拆分为连续的字母和数字片段
def splitAlphanumeric(String s) {
    s.split(/(?<=\D)(?=\d)|(?<=\d)(?=\D)/)
}

// 待排序列表
def list = ["ADF1SD23GF12", "UTRR453FGT3", "NKUY43ERT5", "56GHY123", "MU157FGR234"]

// 执行Excel风格排序
list.sort { a, b ->
    def partsA = splitAlphanumeric(a)
    def partsB = splitAlphanumeric(b)
    
    int minLength = Math.min(partsA.size(), partsB.size())
    for (int i = 0; i < minLength; i++) {
        def partA = partsA[i]
        def partB = partsB[i]
        
        boolean isANumeric = partA.isNumber()
        boolean isBNumeric = partB.isNumber()
        
        int compareResult
        if (isANumeric && isBNumeric) {
            // 数字片段按数值大小比较
            compareResult = partA.toLong() <=> partB.toLong()
        } else if (!isANumeric && !isBNumeric) {
            // 字母片段按不区分大小写的字典序比较(Excel默认行为)
            compareResult = partA.compareToIgnoreCase(partB)
        } else {
            // 字母片段排在数字片段之前
            compareResult = isANumeric ? 1 : -1
        }
        
        if (compareResult != 0) {
            return compareResult
        }
    }
    
    // 前缀完全匹配时,较短的字符串排在前面
    partsA.size() <=> partsB.size()
}

// 输出排序结果
println list

自定义调整说明

  • 如果需要区分大小写排序,将compareToIgnoreCase替换为compareTo即可。
  • 若字符串中包含超大数字(超出Long范围),可改用BigDecimal进行数值比较。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:45:05