expList 数组结构化解析:把「数理/签语/吉凶/详解」拆成字段
# expList 数组结构化解析:把「数理/签语/吉凶/详解」拆成字段
> 接口/接入点:测吉凶 apiCode=1617(四个接入点) · 免费服务 · 适用人群:中高级开发者 · 阅读时间:约 6 分钟
## 核心要点
- `expList` 是字符串数组,每条形如 `前缀:内容`(如 `吉凶:吉`)。用「前缀切分」即可转成结构化对象,便于入库与展示。
- 不同接入点条目数量/前缀不同(手机号/QQ 5 条含 `吉凶`;车牌号 3 条无 `吉凶`),解析需按前缀匹配而非依赖下标。
- 把解析结果存成 `{数理, 签语, 吉凶, 详解, ...}`,前端就能任意组合卡片/徽标。
## Why:为什么要结构化
直接把 `expList` 数组逐行贴出来能用,但你想做「吉凶徽标」「按数理排序」「历史记录查询」时,非结构化文本就不够了。提前把每条拆成字段,后续产品化事半功倍。
## What:输入与输出
- 输入:`showapi_res_body.expList`(array<string>)
- 输出:`{ key: value }` 字典,key 取中文前缀(号码/数理/签语/吉凶/详解/命理/性格暗示…)
## How:前缀切分解析
### Python(通用解析,不依赖下标)
```python
import re, requests
def parse_exp(exp_list):
"""把 expList 字符串数组解析为 {前缀: 内容} 字典。"""
result = {}
if not exp_list:
return result
for item in exp_list:
# 匹配第一个「中文/符号前缀:」分割
m = re.match(r"^([\u4e00-\u9fa5A-Za-z『「【]+)\s*[::]\s*(.*)$", item)
if m:
result[m.group(1).strip("『「【")] = m.group(2).strip()
else:
# 无前缀(如车牌号性格暗示那一条)→ 归入「描述」
result.setdefault("描述", "")
result["描述"] = (result["描述"] + " " + item).strip()
return result
r = requests.post("https://route.showapi.com/1617-1",
params={"appKey": "YOUR_APPKEY"}, data={"mobile": "13770000000"}, timeout=15)
b = r.json()["showapi_res_body"]
data = parse_exp(b.get("expList") or [])
print("吉凶:", data.get("吉凶")) # 吉
print("数理:", data.get("数理")) # 第81数
print("签语:", data.get("签语")) # 最极之数……
```
### Node.js
```javascript
function parseExp(expList) {
const result = {};
(expList || []).forEach((item) => {
const m = item.match(/^([一-龥A-Za-z『「【]+)\s*[::]\s*(.*)$/);
if (m) result[m[1].replace(/[『「【]/g, "")] = m[2].trim();
else result["描述"] = (result["描述"] || "") + " " + item;
});
return result;
}
// 用法:parseExp(body.expList)
```
### cURL(仅取原始数组,解析在前端/后端做)
```bash
curl -X POST "https://route.showapi.com/1617-3?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded" -d "qq=10001"
```
## 返回示例与解析
以 1617-1 为例,解析前后:
```
原始 expList:
["号码:13770000000","数理:第81数","签语:最极之数…","吉凶:吉","详解:主人的性格类型:[自我牺牲/性格被动型]…"]
解析后对象:
{
"号码": "13770000000",
"数理": "第81数",
"签语": "最极之数,还本归元,能得繁业,发达成功",
"吉凶": "吉",
"详解": "主人的性格类型:[自我牺牲/性格被动型]…"
}
```
车牌号(1617-2)解析后则得到 `命理`/`数理`/`描述` 三个键,无 `吉凶` 键——这正是「按前缀匹配」比「按下标」稳的原因。
## 进阶 / 边界
- **不要按下标取**:车牌号仅 3 条、且无 `吉凶` 字段;若代码写 `expList[3]` 取吉凶,在车牌号场景会取到错误内容。永远按前缀 key 取值。
- **多前缀同值**:极少数情况下一条可能含多个「:」,正则只切第一个,余下归内容,符合预期。
- **入库建议**:将解析后的字典落库(如 `fortune_records` 表),字段含 `type`(接入点)、`input`(原输入)、`data`(JSON)、`created_at`,便于做历史查询。
- 公司名可能 `expList` 为空,解析返回空字典,业务按「无结果」处理(见[公司名专篇](https://www.showapi.com/guides/fortune-company-guide-1617))。
## FAQ
**Q:为什么不能按数组下标解析?**
各接入点条目数不同(手机号/QQ 5 条、车牌号 3 条),且字段不同(车牌号无「吉凶」)。按下标会错位,按前缀 key 取值才稳。
**Q:车牌号那条没有前缀的性格暗示怎么处理?**
归入「描述」键即可(见代码 `else` 分支),展示时作为补充说明。
**Q:解析后的「吉凶」能直接当结论用吗?**
可以提炼为徽标,但标注娱乐属性。它来自周易数理,非科学结论。
**Q:要不要缓存解析结果?**
建议缓存(按 input+type 做 key),既提升体验又省免费额度,详见[错误处理与边界容错](https://www.showapi.com/guides/fortune-error-handling-1617)中的缓存思路。
## 相关能力 / 下一步阅读
- [测吉凶返回字段全解:ret_code、remark 与 expList 数组一文读懂](https://www.showapi.com/guides/fortune-response-fields-1617)
- [测吉凶错误处理与边界容错:ret_code 判断、空 expList、参数校验](https://www.showapi.com/guides/fortune-error-handling-1617)
- [手机号测吉凶:如何解析号码数理、签语与性格暗示?](https://www.showapi.com/guides/fortune-mobile-guide-1617)
- **本系列共 13 篇**:查看[测吉凶指南总目录](https://www.showapi.com/guides/fortune-guides-1617)