Golang中按键值对排序含多行值的字符串的最佳方案
解决Go语言中含多行值的key:value字符串排序问题
因为你的字符串里存在GITHUB_PRIVATE_KEY这种值为多行的键,直接按行分割排序会把多行值拆成独立行,导致逻辑错误。正确的思路是先完整解析所有键值对(包括多行值),再按键排序,最后重新拼接成字符串,具体实现步骤如下:
步骤1:解析字符串,提取完整的键值对
遍历字符串的每一行,遇到key:开头的行时,判断是否是需要处理多行值的键(这里是GITHUB_PRIVATE_KEY):
- 如果是多行值键:继续读取后续所有行,直到遇到下一个
key:开头的行或字符串结束,将这些行拼接为该键的完整值。 - 如果是普通单行键:直接提取当前行的value部分。
步骤2:按键排序
将所有提取到的key放入切片,使用sort.Strings()进行字典序排序。
步骤3:重新拼接成排序后的字符串
按照排序后的key顺序,将key:value依次拼接,注意多行值保留原有换行格式。
完整代码示例
package main import ( "sort" "strings" ) func sortKeyValues(input string) string { lines := strings.Split(input, "\n") keyValues := make(map[string]string) var currentKey string var currentValueBuilder strings.Builder for _, line := range lines { // 跳过空行 if strings.TrimSpace(line) == "" { continue } // 判断当前行是否是新的key:开头 colonIdx := strings.Index(line, ":") if colonIdx != -1 { // 如果之前有未处理的键值对,先存入map if currentKey != "" { keyValues[currentKey] = strings.TrimSuffix(currentValueBuilder.String(), "\n") currentValueBuilder.Reset() } currentKey = strings.TrimSpace(line[:colonIdx]) // 写入当前行的value部分 currentValueBuilder.WriteString(strings.TrimSpace(line[colonIdx+1:])) currentValueBuilder.WriteString("\n") // 特殊处理GITHUB_PRIVATE_KEY的多行值 if currentKey == "GITHUB_PRIVATE_KEY" { // 继续读取后续行,直到下一个key:开头的行 for i := 1; i < len(lines); i++ { nextLine := lines[i] if strings.Contains(nextLine, ":") && strings.Index(nextLine, ":") != -1 { break } currentValueBuilder.WriteString(nextLine) currentValueBuilder.WriteString("\n") // 跳过已经处理的行,避免重复遍历 lines = append(lines[:i], lines[i+1:]...) i-- } } } else { // 非key:开头的行,属于当前key的多行值(如果当前有活跃的key) if currentKey != "" { currentValueBuilder.WriteString(line) currentValueBuilder.WriteString("\n") } } } // 处理最后一个键值对 if currentKey != "" { keyValues[currentKey] = strings.TrimSuffix(currentValueBuilder.String(), "\n") } // 提取所有key并排序 keys := make([]string, 0, len(keyValues)) for k := range keyValues { keys = append(keys, k) } sort.Strings(keys) // 重新拼接成结果字符串 var resultBuilder strings.Builder for _, key := range keys { resultBuilder.WriteString(key) resultBuilder.WriteString(": ") resultBuilder.WriteString(keyValues[key]) resultBuilder.WriteString("\n") } return strings.TrimSuffix(resultBuilder.String(), "\n") } func main() { // 示例输入 input := `API_KEY: abc123 GITHUB_PRIVATE_KEY: -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAz... ... -----END RSA PRIVATE KEY----- DATABASE_URL: postgres://user:pass@localhost/db DEBUG: true` sorted := sortKeyValues(input) println(sorted) }
关键说明
- 代码中通过判断
GITHUB_PRIVATE_KEY来处理多行值,如果你还有其他多行值的键,可以扩展判断条件。 - 处理多行值时,会跳过已经读取的行,避免重复遍历,提升效率。
- 最终拼接时保留了原有的换行格式,确保多行值的完整性。
内容的提问来源于stack exchange,提问作者cybertextron
相关产品推荐
相关产品推荐

