小程序 setData 方法支持路徑表達式來設置屬性,例如 setData({"x.y.z": 1})。
微信官方沒有公布路徑表達式的語法規則及解析規則,本文所描述的路徑表達式解析規則由 miniprogrampatch 實現並總結而來。
概述
小程序的路徑表達式基本操作符包括對象屬性訪問符.和數組成員訪問符[]。
例如:
a.b表示訪問對象a的b屬性。a[0]表示訪問數組a的第 2 個成員。a[0]b表示訪問數組a的第 2 個成員的b屬性。
當對象屬性訪問符和數組成員訪問符連在一起時,可以省略書寫屬性訪問符。
數組關閉符與屬性訪問符在特殊情況下省略屬性訪問符會產生歧義,參見下文“路徑表達式解析奇葩規則”。
例如:a.[0].b 等同於 a[0]b。
路徑表達式語法規則
路徑表達式必需滿足以下條件:
- 必需是一個字符串,或者可以轉換成字符串的原始數據類型或者對象。
- 不能是空字符串。
- 不能以數組符號開頭,即路徑不能以字符串
[開頭。 - 不能以未關閉的數組符號加上屬性表達式結尾,例如
a[bc是非法的。 - 不能存在空數組表達式,即不能包含
[]字符。 - 第一個數組表達式關閉符號
]不能在第一個數組表達式起始符號[之前。
路徑表達式解析時會遵循以下規則:
- 連續多個屬性訪問符會被轉換為一個,即
a...b.c等於a.b.c。 - 以屬性訪問符開頭或結尾會被刪除,即
.a.b.等同於a.b。 - 處於結尾的未關閉數組表達式會被刪除,即
x.y[12,x.y[[[[均等同於x.y。 - 連續多個空字符串會被轉換為一個。
路徑表達式解析時奇葩規則:
- 數組表達式中只能包含數字、句號、左方括號。
- 所以數組表達式中不能使用負數,例如
a[-1]是非法的。 - 數組表達式中的句號和左方括號都將被刪除,例如
a[.1.1.]等同於a[11],a[.[.[[1]等同於a[1]。
- 所以數組表達式中不能使用負數,例如
- 每個單獨的數組關閉符號
]都會生成新的數組,而所有單獨的數組關閉符號之間的字符串(不包含屬性訪問符.)將被提取出來拼接成一個屬性名稱。- 例如
x[1]2]3] 4x ]y等同於x[1][0][0][0]23 4x y,但x[1]2]3] 4x ].y等同於x[1][0][0][0]23 4x .y。(此處不滿足上文所說屬性訪問符和數組訪問符在一起時可以省略書寫屬性訪問符的規則)
- 例如
- 當單獨數組關閉符號中間包含屬性訪問符時,優先解析屬性訪問符。
- 例如
x[1]2].a3]x等同於x[1][0]2[0]a3x。
- 例如
示例
合法路徑及其解析結果:
| 原路徑 | 解析結果 |
|---|---|
| "x" | "x", |
| "x.y.z" | "x.y.z", |
| "1.2" | "1.2", |
| "x.y.[2][12]xy.z" | "x.y[2][12]xy.z", |
| "x.y[11.11]z" | "x.y[1111]z", |
| "x.y[.11.]z" | "x.y[11]z", |
| "x[1111" | "x", |
| "x[1[2]23" | "x[12]23", |
| "x[1][2]]]]y" | "x[1][2][0][0][0]y", |
| "x[1].[.[.[2]]]]y" | "x[1][2][0][0][0]y", |
| "x[1]23]4]5]6]y" | "x[1][0][0][0][0]23456y", |
| "x[1]23]4]5x ]6]" | "x[1][0][0][0][0]2345x 6", |
| "x[1]23]4]5]6].y" | "x[1][0][0][0][0]23456.y", |
| "b[1]2].a3].x" | "b[1][0]2[0]a3.x" |
非法路徑及其非法原因:
| 原路徑 | 非法原因 |
|---|---|
| "" | 空字符串非法 |
| "[1]x" | 數組開頭非法 |
| "x]][0]" | 第一個 ] 出現在第一個 [ 之前 |
| "x[a]" | 數組中只能包含數字 |
| "x[abc" | 未關閉數組符號,且緊跟非數字 |
| "x[]" | 存在空數組符號 |
| "x[-1]" | 數組中只能包含數字 |
| "x[ 1]" | 數組中只能包含數字 |
| "x[.]" | 數組中的句號會被刪除,導致存在空數組 |
| "x[1 1]" | 數組中只能包含數字 |
| "x[ ]" | 數組中只能包含數字 |
小程序路徑表達式解析方案具體實現及測試參見 miniprogrampatch
