在Go中解析此类C代码数组的最佳方法是使用正则表达式提取十六进制数据,然后转换为字节切片。以下是具体实现:
package main
import (
"encoding/hex"
"fmt"
"regexp"
"strings"
)
func parseCArray(content string) ([]byte, error) {
// 匹配十六进制数据部分
re := regexp.MustCompile(`\{([^}]+)\}`)
match := re.FindStringSubmatch(content)
if match == nil {
return nil, fmt.Errorf("未找到数组数据")
}
// 清理数据:移除空格、换行和逗号
dataStr := strings.ReplaceAll(match[1], "\n", "")
dataStr = strings.ReplaceAll(dataStr, " ", "")
hexStrings := strings.Split(dataStr, ",")
// 转换十六进制字符串为字节
var result []byte
for _, hexStr := range hexStrings {
if hexStr == "" {
continue
}
// 移除0x前缀
cleanHex := strings.TrimPrefix(hexStr, "0x")
b, err := hex.DecodeString(cleanHex)
if err != nil {
return nil, fmt.Errorf("解析十六进制失败: %v", err)
}
result = append(result, b...)
}
return result, nil
}
func main() {
cCode := `#define index_html_gz_len 12
const uint8_t index_html_gz[] PROGMEM = {
0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xec,0xbd,0x8b};`
data, err := parseCArray(cCode)
if err != nil {
fmt.Printf("解析失败: %v\n", err)
return
}
fmt.Printf("解析结果: %v\n", data)
fmt.Printf("十六进制: %x\n", data)
fmt.Printf("长度: %d\n", len(data))
}
如果要从文件读取,可以这样处理:
func parseCArrayFromFile(filename string) ([]byte, error) {
content, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
return parseCArray(string(content))
}
对于更复杂的C数组格式,可以调整正则表达式:
// 匹配多种格式的十六进制数据
re := regexp.MustCompile(`\{[\s\S]*?([0-9a-fA-Fx,\s\n]+)[\s\S]*?\}`)
这种方法直接提取十六进制数据并转换为字节切片,适用于嵌入式开发中常见的C数组导出场景。