(wip) regex match op

This commit is contained in:
Mike Farah 2021-07-07 22:47:16 +10:00
parent cc7ea83506
commit 573618e4ce
3 changed files with 44 additions and 64 deletions

View File

@ -1,47 +1,13 @@
# String Operators
## Match string
Given a sample.yml file of:
```yaml
cat
```
then
```bash
yq eval 'match("at")' sample.yml
```
will output
```yaml
string: at
offset: 1
length: 2
captures: []
```
## Match string, case insensitive
Given a sample.yml file of:
```yaml
cAt
```
then
```bash
yq eval 'match("(?i)at")' sample.yml
```
will output
```yaml
string: At
offset: 1
length: 2
captures: []
```
## Match with capture groups
## Match with names capture groups
Given a sample.yml file of:
```yaml
a cat
```
then
```bash
yq eval 'match("c(.t)")' sample.yml
yq eval 'match("c(?P<cool>.t)")' sample.yml
```
will output
```yaml
@ -52,5 +18,6 @@ captures:
- string: at
offset: 3
length: 2
name: cool
```

View File

@ -74,24 +74,29 @@ func substituteStringOperator(d *dataTreeNavigator, context Context, expressionN
}
func addMatch(original []*yaml.Node, match string, offset int) []*yaml.Node {
return append(original,
func addMatch(original []*yaml.Node, match string, offset int, name string) []*yaml.Node {
newContent := append(original,
createScalarNode("string", "string"),
createScalarNode(match, match),
createScalarNode("offset", "offset"),
createScalarNode(offset, fmt.Sprintf("%v", offset)),
createScalarNode("length", "length"),
createScalarNode(len(match), fmt.Sprintf("%v", len(match))))
if name != "" {
newContent = append(newContent,
createScalarNode("name", "name"),
createScalarNode(name, name),
)
}
return newContent
}
func match(regEx *regexp.Regexp, candidate *CandidateNode, value string, results *list.List) {
// captures = FindAllStringSubmatch
// FindAllStringSubmatchIndex = offset?
//string array
// subNames := regEx.SubexpNames()
subNames := regEx.SubexpNames()
log.Debugf("subNames %v", subNames)
//array of arrays
allMatches := regEx.FindAllStringSubmatch(value, -1)
allIndices := regEx.FindAllStringSubmatchIndex(value, -1)
@ -100,12 +105,12 @@ func match(regEx *regexp.Regexp, candidate *CandidateNode, value string, results
match, submatches := matches[0], matches[1:]
for j, submatch := range submatches {
captureNode := &yaml.Node{Kind: yaml.MappingNode}
captureNode.Content = addMatch(capturesNode.Content, submatch, allIndices[i][2+j*2])
captureNode.Content = addMatch(capturesNode.Content, submatch, allIndices[i][2+j*2], subNames[j+1])
capturesNode.Content = append(capturesNode.Content, captureNode)
}
node := &yaml.Node{Kind: yaml.MappingNode}
node.Content = addMatch(node.Content, match, allIndices[i][0])
node.Content = addMatch(node.Content, match, allIndices[i][0], "")
node.Content = append(node.Content,
createScalarNode("captures", "captures"),
capturesNode,

View File

@ -13,28 +13,36 @@ var stringsOperatorScenarios = []expressionScenario{
// "D0, P[], (!!str)::cat; meow; 1; ; true\n",
// },
// },
// {
// description: "Match string",
// document: `cat`,
// expression: `match("at")`,
// expected: []string{
// "D0, P[], ()::string: at\noffset: 1\nlength: 2\ncaptures: []\n",
// },
// },
// {
// description: "Match string, case insensitive",
// document: `cAt`,
// expression: `match("(?i)at")`,
// expected: []string{
// "D0, P[], ()::string: At\noffset: 1\nlength: 2\ncaptures: []\n",
// },
// },
// {
// description: "Match with capture groups",
// document: `a cat`,
// expression: `match("c(.t)")`,
// expected: []string{
// "D0, P[], ()::string: cat\noffset: 2\nlength: 3\ncaptures:\n - string: at\n offset: 3\n length: 2\n",
// },
// },
{
description: "Match string",
document: `cat`,
expression: `match("at")`,
expected: []string{
"D0, P[], ()::string: at\noffset: 1\nlength: 2\ncaptures: []\n",
},
},
{
description: "Match string, case insensitive",
document: `cAt`,
expression: `match("(?i)at")`,
expected: []string{
"D0, P[], ()::string: At\noffset: 1\nlength: 2\ncaptures: []\n",
},
},
{
description: "Match with capture groups",
description: "Match with names capture groups",
document: `a cat`,
expression: `match("c(.t)")`,
expression: `match("c(?P<cool>.t)")`,
expected: []string{
"D0, P[], ()::string: cat\noffset: 2\nlength: 3\ncaptures:\n - string: at\n offset: 3\n length: 2\n",
"D0, P[], ()::string: cat\noffset: 2\nlength: 3\ncaptures:\n - string: at\n offset: 3\n length: 2\n name: cool\n",
},
},
// {