mirror of
https://github.com/mikefarah/yq.git
synced 2026-09-01 14:14:52 +08:00
Add string slicing support (#2639)
* Initial plan * Add string slicing support to yq Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/a8525fbb-77a7-4bb0-a3a7-b24f99ae8710 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com> * Fix sliceStringNode signature and fix test descriptions/expressions Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/58726b13-68ae-4f93-971f-eb70459edcf4 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com> * Update pkg/yqlib/operator_slice.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix array slice out-of-bounds panic with very negative indices Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/7c146762-d251-45fd-8555-2488f59fc57b Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com> * S2-S4: tighten lexer condition, fix doc header, add Unicode example Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/ec06083e-e20a-45d2-bf7e-4e1fa7be1073 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com> * Fix spelling: multibyte -> multi-byte in Unicode test subdescription Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/6e7b304b-5b52-4e89-8bad-ba22813305c7 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com> Co-authored-by: Mike Farah <mikefarah@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
mikefarah
Copilot
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Mike Farah
parent
68f0322ba3
commit
3b2423e871
@@ -31,6 +31,24 @@ func clampSliceIndex(index, length int) int {
|
||||
return index
|
||||
}
|
||||
|
||||
func sliceStringNode(lhsNode *CandidateNode, firstNumber int, secondNumber int) *CandidateNode {
|
||||
runes := []rune(lhsNode.Value)
|
||||
length := len(runes)
|
||||
|
||||
relativeFirstNumber := clampSliceIndex(firstNumber, length)
|
||||
relativeSecondNumber := clampSliceIndex(secondNumber, length)
|
||||
if relativeSecondNumber < relativeFirstNumber {
|
||||
relativeSecondNumber = relativeFirstNumber
|
||||
}
|
||||
|
||||
log.Debugf("sliceStringNode: slice from %v to %v", relativeFirstNumber, relativeSecondNumber)
|
||||
|
||||
slicedString := string(runes[relativeFirstNumber:relativeSecondNumber])
|
||||
replacement := lhsNode.CreateReplacement(ScalarNode, lhsNode.Tag, slicedString)
|
||||
replacement.Style = lhsNode.Style
|
||||
return replacement
|
||||
}
|
||||
|
||||
func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||
|
||||
log.Debug("slice array operator!")
|
||||
@@ -43,16 +61,21 @@ func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *E
|
||||
lhsNode := el.Value.(*CandidateNode)
|
||||
|
||||
firstNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.LHS)
|
||||
|
||||
if err != nil {
|
||||
return Context{}, err
|
||||
}
|
||||
relativeFirstNumber := clampSliceIndex(firstNumber, len(lhsNode.Content))
|
||||
|
||||
secondNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.RHS)
|
||||
if err != nil {
|
||||
return Context{}, err
|
||||
}
|
||||
|
||||
if lhsNode.Kind == ScalarNode && lhsNode.guessTagFromCustomType() == "!!str" {
|
||||
results.PushBack(sliceStringNode(lhsNode, firstNumber, secondNumber))
|
||||
continue
|
||||
}
|
||||
|
||||
relativeFirstNumber := clampSliceIndex(firstNumber, len(lhsNode.Content))
|
||||
relativeSecondNumber := clampSliceIndex(secondNumber, len(lhsNode.Content))
|
||||
|
||||
log.Debugf("calculateIndicesToTraverse: slice from %v to %v", relativeFirstNumber, relativeSecondNumber)
|
||||
|
||||
Reference in New Issue
Block a user