mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 00:39:13 +00:00
fix(wildcard): partial match ignoring consumed pattern (#1765)
* tests(wildcard): ? * really? * Franklin * remember when regex was easy * == * why not. * I need an adult. * Update match_test.go * tests + readability * back to basics
This commit is contained in:
parent
2386a9db31
commit
5df6e78d3b
2 changed files with 52 additions and 22 deletions
|
@ -41,28 +41,7 @@ func match(pattern, name string, simple bool) (matched bool) {
|
||||||
((wildEnd && strings.Count(pattern, "*") == 1) || // egg?bert*
|
((wildEnd && strings.Count(pattern, "*") == 1) || // egg?bert*
|
||||||
(len(pattern) == len(name) && !strings.Contains(pattern, "*"))) { // egg?bert?
|
(len(pattern) == len(name) && !strings.Contains(pattern, "*"))) { // egg?bert?
|
||||||
|
|
||||||
base := 0
|
return matchComplex(name, pattern, wildEnd)
|
||||||
for base < len(name) {
|
|
||||||
i := strings.IndexRune(pattern[base:], '?')
|
|
||||||
if i == -1 {
|
|
||||||
if (wildEnd && !strings.HasPrefix(name[base:], pattern[base:len(pattern)-1])) || // egg*
|
|
||||||
(!wildEnd && name[base:] != pattern[base:]) { // egg
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
base = len(name)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
offset := base + i
|
|
||||||
if len(name) < offset || name[base:offset] != pattern[base:offset] {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
base = offset + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return base == len(name)
|
|
||||||
} else if strings.HasPrefix(pattern, "*") && strings.HasSuffix(pattern, "*") && // *egg*
|
} else if strings.HasPrefix(pattern, "*") && strings.HasSuffix(pattern, "*") && // *egg*
|
||||||
(simple || (!simple && !strings.Contains(pattern, "?"))) && // simple is fine, if not we need to check for ? and skip if so.
|
(simple || (!simple && !strings.Contains(pattern, "?"))) && // simple is fine, if not we need to check for ? and skip if so.
|
||||||
strings.Count(pattern, "*") == 2 { // make sure that we have no other wildcards.
|
strings.Count(pattern, "*") == 2 { // make sure that we have no other wildcards.
|
||||||
|
@ -72,6 +51,35 @@ func match(pattern, name string, simple bool) (matched bool) {
|
||||||
return deepMatchRune(name, pattern, simple, pattern, false)
|
return deepMatchRune(name, pattern, simple, pattern, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func matchComplex(name, pattern string, wildEnd bool) bool {
|
||||||
|
base := 0
|
||||||
|
consumedPattern := 0
|
||||||
|
|
||||||
|
for base < len(name) && consumedPattern < len(pattern) {
|
||||||
|
i := strings.IndexRune(pattern[base:], '?')
|
||||||
|
if i == -1 {
|
||||||
|
if (wildEnd && !strings.HasPrefix(name[base:], pattern[base:len(pattern)-1])) || // egg*
|
||||||
|
(!wildEnd && name[base:] != pattern[base:]) { // egg
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
base = len(name)
|
||||||
|
consumedPattern = len(pattern)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := base + i
|
||||||
|
if len(name) < offset || name[base:offset] != pattern[base:offset] {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
base = offset + 1
|
||||||
|
consumedPattern = base
|
||||||
|
}
|
||||||
|
|
||||||
|
return base == len(name) && consumedPattern == len(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
func MatchSliceSimple(pattern []string, name string) (matched bool) {
|
func MatchSliceSimple(pattern []string, name string) (matched bool) {
|
||||||
return matchSlice(pattern, name, true)
|
return matchSlice(pattern, name, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,26 @@ func TestMatch(t *testing.T) {
|
||||||
text: "them",
|
text: "them",
|
||||||
matched: false,
|
matched: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
pattern: "t?q*",
|
||||||
|
text: "tam e",
|
||||||
|
matched: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: "Hard?Quiz*",
|
||||||
|
text: "HardX 24 10 12 Ella Reese XXX 1080p MP4-WRB",
|
||||||
|
matched: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: "Hard?Quiz*",
|
||||||
|
text: "HardX",
|
||||||
|
matched: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: "T?Q*",
|
||||||
|
text: "T?Q",
|
||||||
|
matched: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
// Iterating over the test cases, call the function under test and assert the output.
|
// Iterating over the test cases, call the function under test and assert the output.
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@ -157,6 +177,7 @@ func TestMatchSliceSimple(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{[]string{"*", "test"}, "test", true},
|
{[]string{"*", "test"}, "test", true},
|
||||||
{[]string{"te?t", "tost", "random"}, "tost", true},
|
{[]string{"te?t", "tost", "random"}, "tost", true},
|
||||||
|
{[]string{"te?t", "t?s?", "random"}, "tost", false},
|
||||||
{[]string{"*st", "n?st", "l*st"}, "list", true},
|
{[]string{"*st", "n?st", "l*st"}, "list", true},
|
||||||
{[]string{"?", "?*", "?**"}, "t", false},
|
{[]string{"?", "?*", "?**"}, "t", false},
|
||||||
{[]string{"a", "b", "c"}, "d", false},
|
{[]string{"a", "b", "c"}, "d", false},
|
||||||
|
@ -182,6 +203,7 @@ func TestMatchSlice(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{[]string{"*", "test", "t?st"}, "test", true},
|
{[]string{"*", "test", "t?st"}, "test", true},
|
||||||
{[]string{"te?t", "t?st", "random"}, "tost", true},
|
{[]string{"te?t", "t?st", "random"}, "tost", true},
|
||||||
|
{[]string{"te?t", "t?s?", "random"}, "tost", true},
|
||||||
{[]string{"te?t", "t??e?", "random"}, "toser", true},
|
{[]string{"te?t", "t??e?", "random"}, "toser", true},
|
||||||
{[]string{"*st", "n?st", "l*st"}, "list", true},
|
{[]string{"*st", "n?st", "l*st"}, "list", true},
|
||||||
{[]string{"?", "??", "???"}, "t", true},
|
{[]string{"?", "??", "???"}, "t", true},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue