5
5
"fmt"
6
6
"github.com/tidwall/gjson"
7
7
"github.com/tidwall/sjson"
8
+ "regexp"
9
+ "strconv"
8
10
"strings"
9
11
)
10
12
@@ -151,7 +153,9 @@ func checkConditions(jsonStr string, conditions []ConditionOperation, logic stri
151
153
}
152
154
153
155
func checkSingleCondition (jsonStr string , condition ConditionOperation ) (bool , error ) {
154
- value := gjson .Get (jsonStr , condition .Path )
156
+ // 处理负数索引
157
+ path := processNegativeIndex (jsonStr , condition .Path )
158
+ value := gjson .Get (jsonStr , path )
155
159
if ! value .Exists () {
156
160
if condition .PassMissingKey {
157
161
return true , nil
@@ -177,6 +181,37 @@ func checkSingleCondition(jsonStr string, condition ConditionOperation) (bool, e
177
181
return result , nil
178
182
}
179
183
184
+ func processNegativeIndex (jsonStr string , path string ) string {
185
+ re := regexp .MustCompile (`\.(-\d+)` )
186
+ matches := re .FindAllStringSubmatch (path , - 1 )
187
+
188
+ if len (matches ) == 0 {
189
+ return path
190
+ }
191
+
192
+ result := path
193
+ for _ , match := range matches {
194
+ negIndex := match [1 ]
195
+ index , _ := strconv .Atoi (negIndex )
196
+
197
+ arrayPath := strings .Split (path , negIndex )[0 ]
198
+ if strings .HasSuffix (arrayPath , "." ) {
199
+ arrayPath = arrayPath [:len (arrayPath )- 1 ]
200
+ }
201
+
202
+ array := gjson .Get (jsonStr , arrayPath )
203
+ if array .IsArray () {
204
+ length := len (array .Array ())
205
+ actualIndex := length + index
206
+ if actualIndex >= 0 && actualIndex < length {
207
+ result = strings .Replace (result , match [0 ], "." + strconv .Itoa (actualIndex ), 1 )
208
+ }
209
+ }
210
+ }
211
+
212
+ return result
213
+ }
214
+
180
215
// compareGjsonValues 直接比较两个gjson.Result,支持所有比较模式
181
216
func compareGjsonValues (jsonValue , targetValue gjson.Result , mode string ) (bool , error ) {
182
217
switch mode {
@@ -274,21 +309,25 @@ func applyOperations(jsonStr string, operations []ParamOperation) (string, error
274
309
if ! ok {
275
310
continue // 条件不满足,跳过当前操作
276
311
}
312
+ // 处理路径中的负数索引
313
+ opPath := processNegativeIndex (result , op .Path )
314
+ opFrom := processNegativeIndex (result , op .From )
315
+ opTo := processNegativeIndex (result , op .To )
277
316
278
317
switch op .Mode {
279
318
case "delete" :
280
- result , err = sjson .Delete (result , op . Path )
319
+ result , err = sjson .Delete (result , opPath )
281
320
case "set" :
282
- if op .KeepOrigin && gjson .Get (result , op . Path ).Exists () {
321
+ if op .KeepOrigin && gjson .Get (result , opPath ).Exists () {
283
322
continue
284
323
}
285
- result , err = sjson .Set (result , op . Path , op .Value )
324
+ result , err = sjson .Set (result , opPath , op .Value )
286
325
case "move" :
287
- result , err = moveValue (result , op . From , op . To )
326
+ result , err = moveValue (result , opFrom , opTo )
288
327
case "prepend" :
289
- result , err = modifyValue (result , op . Path , op .Value , op .KeepOrigin , true )
328
+ result , err = modifyValue (result , opPath , op .Value , op .KeepOrigin , true )
290
329
case "append" :
291
- result , err = modifyValue (result , op . Path , op .Value , op .KeepOrigin , false )
330
+ result , err = modifyValue (result , opPath , op .Value , op .KeepOrigin , false )
292
331
default :
293
332
return "" , fmt .Errorf ("unknown operation: %s" , op .Mode )
294
333
}
0 commit comments