71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
package cccode
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
// Parsed 是解析后的 MA 码各段。
|
|
type Parsed struct {
|
|
Root string
|
|
CountryCode string
|
|
IndustryNode string
|
|
OrgNode string
|
|
Category string
|
|
Year int
|
|
Sequence uint64
|
|
}
|
|
|
|
// ccCodePattern 匹配六段式 MA 码:
|
|
// MA.156.{industry}.{org}/{category}/{yyyy}{sequence}
|
|
var ccCodePattern = regexp.MustCompile(
|
|
`^(MA)\.(\d{3})\.([0-9A-Za-z]+)\.([0-9A-Za-z]+)/([A-Z]{2})/(\d{4})(\d+)$`)
|
|
|
|
// Parse 将 MA 码字符串解析为结构化字段;格式非法返回错误(需求4 校验基础)。
|
|
func Parse(code string) (Parsed, error) {
|
|
m := ccCodePattern.FindStringSubmatch(code)
|
|
if m == nil {
|
|
return Parsed{}, fmt.Errorf("cccode: invalid format: %s", code)
|
|
}
|
|
year, _ := strconv.Atoi(m[6])
|
|
seq, err := strconv.ParseUint(m[7], 10, 64)
|
|
if err != nil {
|
|
return Parsed{}, fmt.Errorf("cccode: invalid sequence: %w", err)
|
|
}
|
|
return Parsed{
|
|
Root: m[1],
|
|
CountryCode: m[2],
|
|
IndustryNode: m[3],
|
|
OrgNode: m[4],
|
|
Category: m[5],
|
|
Year: year,
|
|
Sequence: seq,
|
|
}, nil
|
|
}
|
|
|
|
// IsValid 仅校验格式合法性。
|
|
func IsValid(code string) bool {
|
|
return ccCodePattern.MatchString(code)
|
|
}
|
|
|
|
// EpisodeSubID 生成集级子标识:{ccCode}#E{NN}。
|
|
// 整剧用 MA 码,单集用子标识,便于按集验真/追更/下架。
|
|
func EpisodeSubID(ccCode string, episode int) string {
|
|
return fmt.Sprintf("%s#E%02d", ccCode, episode)
|
|
}
|
|
|
|
// episodeSubPattern 匹配集级子标识后缀。
|
|
var episodeSubPattern = regexp.MustCompile(`^(.+)#E(\d+)$`)
|
|
|
|
// ParseEpisodeSubID 拆解集级子标识,返回主 MA 码与集号。
|
|
// 若无 #E 后缀,episode 返回 0(表示整剧)。
|
|
func ParseEpisodeSubID(subID string) (ccCode string, episode int) {
|
|
m := episodeSubPattern.FindStringSubmatch(subID)
|
|
if m == nil {
|
|
return subID, 0
|
|
}
|
|
ep, _ := strconv.Atoi(m[2])
|
|
return m[1], ep
|
|
}
|