@ -121,7 +121,7 @@ func TestFastRegexMatcher_MatchString(t *testing.T) {
t . Parallel ( )
m , err := NewFastRegexMatcher ( r )
require . NoError ( t , err )
re := regexp . MustCompile ( "^(?:" + r + ")$" )
re := regexp . MustCompile ( "^(?s :" + r + ")$" )
require . Equal ( t , re . MatchString ( v ) , m . MatchString ( v ) )
} )
}
@ -167,7 +167,7 @@ func TestOptimizeConcatRegex(t *testing.T) {
}
for _ , c := range cases {
parsed , err := syntax . Parse ( c . regex , syntax . Perl )
parsed , err := syntax . Parse ( c . regex , syntax . Perl | syntax . DotNL )
require . NoError ( t , err )
prefix , suffix , contains := optimizeConcatRegex ( parsed )
@ -248,7 +248,7 @@ func TestFindSetMatches(t *testing.T) {
c := c
t . Run ( c . pattern , func ( t * testing . T ) {
t . Parallel ( )
parsed , err := syntax . Parse ( c . pattern , syntax . Perl )
parsed , err := syntax . Parse ( c . pattern , syntax . Perl | syntax . DotNL )
require . NoError ( t , err )
matches , actualCaseSensitive := findSetMatches ( parsed )
require . Equal ( t , c . expMatches , matches )
@ -348,15 +348,15 @@ func TestStringMatcherFromRegexp(t *testing.T) {
pattern string
exp StringMatcher
} {
{ ".*" , anyS tringWitho utNewlin eMatcher{ } } ,
{ ".*?" , anyS tringWitho utNewlin eMatcher{ } } ,
{ ".*" , trueMatcher { } } ,
{ ".*?" , trueMatcher { } } ,
{ "(?s:.*)" , trueMatcher { } } ,
{ "(.*)" , anyS tringWitho utNewlin eMatcher{ } } ,
{ "^.*$" , anyS tringWitho utNewlin eMatcher{ } } ,
{ ".+" , & anyNonEmptyStringMatcher { matchNL : fals e} } ,
{ "(.*)" , trueMatcher { } } ,
{ "^.*$" , trueMatcher { } } ,
{ ".+" , & anyNonEmptyStringMatcher { matchNL : tru e} } ,
{ "(?s:.+)" , & anyNonEmptyStringMatcher { matchNL : true } } ,
{ "^.+$" , & anyNonEmptyStringMatcher { matchNL : fals e} } ,
{ "(.+)" , & anyNonEmptyStringMatcher { matchNL : fals e} } ,
{ "^.+$" , & anyNonEmptyStringMatcher { matchNL : tru e} } ,
{ "(.+)" , & anyNonEmptyStringMatcher { matchNL : tru e} } ,
{ "" , emptyStringMatcher { } } ,
{ "^$" , emptyStringMatcher { } } ,
{ "^foo$" , & equalStringMatcher { s : "foo" , caseSensitive : true } } ,
@ -366,23 +366,23 @@ func TestStringMatcherFromRegexp(t *testing.T) {
{ ` (?i:((foo1|foo2|bar))) ` , orStringMatcher ( [ ] StringMatcher { orStringMatcher ( [ ] StringMatcher { & equalStringMatcher { s : "FOO1" , caseSensitive : false } , & equalStringMatcher { s : "FOO2" , caseSensitive : false } } ) , & equalStringMatcher { s : "BAR" , caseSensitive : false } } ) } ,
{ "^((?i:foo|oo)|(bar))$" , orStringMatcher ( [ ] StringMatcher { & equalStringMatcher { s : "FOO" , caseSensitive : false } , & equalStringMatcher { s : "OO" , caseSensitive : false } , & equalStringMatcher { s : "bar" , caseSensitive : true } } ) } ,
{ "(?i:(foo1|foo2|bar))" , orStringMatcher ( [ ] StringMatcher { orStringMatcher ( [ ] StringMatcher { & equalStringMatcher { s : "FOO1" , caseSensitive : false } , & equalStringMatcher { s : "FOO2" , caseSensitive : false } } ) , & equalStringMatcher { s : "BAR" , caseSensitive : false } } ) } ,
{ ".*foo.*" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : anyS tringWitho utNewlin eMatcher{ } , right : anyS tringWitho utNewlin eMatcher{ } } } ,
{ "(.*)foo.*" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : anyS tringWitho utNewlin eMatcher{ } , right : anyS tringWitho utNewlin eMatcher{ } } } ,
{ "(.*)foo(.*)" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : anyS tringWitho utNewlin eMatcher{ } , right : anyS tringWitho utNewlin eMatcher{ } } } ,
{ "(.+)foo(.*)" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : & anyNonEmptyStringMatcher { matchNL : fals e} , right : anyS tringWitho utNewlin eMatcher{ } } } ,
{ "^.+foo.+" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : & anyNonEmptyStringMatcher { matchNL : fals e} , right : & anyNonEmptyStringMatcher { matchNL : fals e} } } ,
{ "^(.*)(foo)(.*)$" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : anyS tringWitho utNewlin eMatcher{ } , right : anyS tringWitho utNewlin eMatcher{ } } } ,
{ "^(.*)(foo|foobar)(.*)$" , & containsStringMatcher { substrings : [ ] string { "foo" , "foobar" } , left : anyS tringWitho utNewlin eMatcher{ } , right : anyS tringWitho utNewlin eMatcher{ } } } ,
{ "^(.*)(foo|foobar)(.+)$" , & containsStringMatcher { substrings : [ ] string { "foo" , "foobar" } , left : anyS tringWitho utNewlin eMatcher{ } , right : & anyNonEmptyStringMatcher { matchNL : fals e} } } ,
{ "^(.*)(bar|b|buzz)(.+)$" , & containsStringMatcher { substrings : [ ] string { "bar" , "b" , "buzz" } , left : anyS tringWitho utNewlin eMatcher{ } , right : & anyNonEmptyStringMatcher { matchNL : fals e} } } ,
{ ".*foo.*" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : trueMatcher { } , right : trueMatcher { } } } ,
{ "(.*)foo.*" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : trueMatcher { } , right : trueMatcher { } } } ,
{ "(.*)foo(.*)" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : trueMatcher { } , right : trueMatcher { } } } ,
{ "(.+)foo(.*)" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : & anyNonEmptyStringMatcher { matchNL : tru e} , right : trueMatcher { } } } ,
{ "^.+foo.+" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : & anyNonEmptyStringMatcher { matchNL : tru e} , right : & anyNonEmptyStringMatcher { matchNL : tru e} } } ,
{ "^(.*)(foo)(.*)$" , & containsStringMatcher { substrings : [ ] string { "foo" } , left : trueMatcher { } , right : trueMatcher { } } } ,
{ "^(.*)(foo|foobar)(.*)$" , & containsStringMatcher { substrings : [ ] string { "foo" , "foobar" } , left : trueMatcher { } , right : trueMatcher { } } } ,
{ "^(.*)(foo|foobar)(.+)$" , & containsStringMatcher { substrings : [ ] string { "foo" , "foobar" } , left : trueMatcher { } , right : & anyNonEmptyStringMatcher { matchNL : tru e} } } ,
{ "^(.*)(bar|b|buzz)(.+)$" , & containsStringMatcher { substrings : [ ] string { "bar" , "b" , "buzz" } , left : trueMatcher { } , right : & anyNonEmptyStringMatcher { matchNL : tru e} } } ,
{ "10\\.0\\.(1|2)\\.+" , nil } ,
{ "10\\.0\\.(1|2).+" , & containsStringMatcher { substrings : [ ] string { "10.0.1" , "10.0.2" } , left : nil , right : & anyNonEmptyStringMatcher { matchNL : fals e} } } ,
{ "^.+foo" , & literalSuffixStringMatcher { left : & anyNonEmptyStringMatcher { } , suffix : "foo" , suffixCaseSensitive : true } } ,
{ "foo-.*$" , & literalPrefixSensitiveStringMatcher { prefix : "foo-" , right : anyS tringWitho utNewlin eMatcher{ } } } ,
{ "(prometheus|api_prom)_api_v1_.+" , & containsStringMatcher { substrings : [ ] string { "prometheus_api_v1_" , "api_prom_api_v1_" } , left : nil , right : & anyNonEmptyStringMatcher { matchNL : fals e} } } ,
{ "^((.*)(bar|b|buzz)(.+)|foo)$" , orStringMatcher ( [ ] StringMatcher { & containsStringMatcher { substrings : [ ] string { "bar" , "b" , "buzz" } , left : anyS tringWitho utNewlin eMatcher{ } , right : & anyNonEmptyStringMatcher { matchNL : fals e} } , & equalStringMatcher { s : "foo" , caseSensitive : true } } ) } ,
{ "((fo(bar))|.+foo)" , orStringMatcher ( [ ] StringMatcher { orStringMatcher ( [ ] StringMatcher { & equalStringMatcher { s : "fobar" , caseSensitive : true } } ) , & literalSuffixStringMatcher { suffix : "foo" , suffixCaseSensitive : true , left : & anyNonEmptyStringMatcher { matchNL : fals e} } } ) } ,
{ "(.+)/(gateway|cortex-gw|cortex-gw-internal)" , & containsStringMatcher { substrings : [ ] string { "/gateway" , "/cortex-gw" , "/cortex-gw-internal" } , left : & anyNonEmptyStringMatcher { matchNL : fals e} , right : nil } } ,
{ "10\\.0\\.(1|2).+" , & containsStringMatcher { substrings : [ ] string { "10.0.1" , "10.0.2" } , left : nil , right : & anyNonEmptyStringMatcher { matchNL : tru e} } } ,
{ "^.+foo" , & literalSuffixStringMatcher { left : & anyNonEmptyStringMatcher { matchNL : true } , suffix : "foo" , suffixCaseSensitive : true } } ,
{ "foo-.*$" , & literalPrefixSensitiveStringMatcher { prefix : "foo-" , right : trueMatcher { } } } ,
{ "(prometheus|api_prom)_api_v1_.+" , & containsStringMatcher { substrings : [ ] string { "prometheus_api_v1_" , "api_prom_api_v1_" } , left : nil , right : & anyNonEmptyStringMatcher { matchNL : tru e} } } ,
{ "^((.*)(bar|b|buzz)(.+)|foo)$" , orStringMatcher ( [ ] StringMatcher { & containsStringMatcher { substrings : [ ] string { "bar" , "b" , "buzz" } , left : trueMatcher { } , right : & anyNonEmptyStringMatcher { matchNL : tru e} } , & equalStringMatcher { s : "foo" , caseSensitive : true } } ) } ,
{ "((fo(bar))|.+foo)" , orStringMatcher ( [ ] StringMatcher { orStringMatcher ( [ ] StringMatcher { & equalStringMatcher { s : "fobar" , caseSensitive : true } } ) , & literalSuffixStringMatcher { suffix : "foo" , suffixCaseSensitive : true , left : & anyNonEmptyStringMatcher { matchNL : tru e} } } ) } ,
{ "(.+)/(gateway|cortex-gw|cortex-gw-internal)" , & containsStringMatcher { substrings : [ ] string { "/gateway" , "/cortex-gw" , "/cortex-gw-internal" } , left : & anyNonEmptyStringMatcher { matchNL : tru e} , right : nil } } ,
// we don't support case insensitive matching for contains.
// This is because there's no strings.IndexOfFold function.
// We can revisit later if this is really popular by using strings.ToUpper.
@ -393,15 +393,15 @@ func TestStringMatcherFromRegexp(t *testing.T) {
{ ".*foo.*bar.*" , nil } ,
{ ` \d* ` , nil } ,
{ "." , nil } ,
{ "/|/bar.*" , & literalPrefixSensitiveStringMatcher { prefix : "/" , right : orStringMatcher { emptyStringMatcher { } , & literalPrefixSensitiveStringMatcher { prefix : "bar" , right : anyS tringWitho utNewlin eMatcher{ } } } } } ,
{ "/|/bar.*" , & literalPrefixSensitiveStringMatcher { prefix : "/" , right : orStringMatcher { emptyStringMatcher { } , & literalPrefixSensitiveStringMatcher { prefix : "bar" , right : trueMatcher { } } } } } ,
// This one is not supported because `stringMatcherFromRegexp` is not reentrant for syntax.OpConcat.
// It would make the code too complex to handle it.
{ "(.+)/(foo.*|bar$)" , nil } ,
// Case sensitive alternate with same literal prefix and .* suffix.
{ "(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*)" , & literalPrefixSensitiveStringMatcher { prefix : "xyz-016a-ixb-" , right : orStringMatcher { & literalPrefixSensitiveStringMatcher { prefix : "dp" , right : anyS tringWitho utNewlin eMatcher{ } } , & literalPrefixSensitiveStringMatcher { prefix : "op" , right : anyS tringWitho utNewlin eMatcher{ } } } } } ,
{ "(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*)" , & literalPrefixSensitiveStringMatcher { prefix : "xyz-016a-ixb-" , right : orStringMatcher { & literalPrefixSensitiveStringMatcher { prefix : "dp" , right : trueMatcher { } } , & literalPrefixSensitiveStringMatcher { prefix : "op" , right : trueMatcher { } } } } } ,
// Case insensitive alternate with same literal prefix and .* suffix.
{ "(?i:(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*))" , & literalPrefixInsensitiveStringMatcher { prefix : "XYZ-016A-IXB-" , right : orStringMatcher { & literalPrefixInsensitiveStringMatcher { prefix : "DP" , right : anyS tringWitho utNewlin eMatcher{ } } , & literalPrefixInsensitiveStringMatcher { prefix : "OP" , right : anyS tringWitho utNewlin eMatcher{ } } } } } ,
{ "(?i)(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*)" , & literalPrefixInsensitiveStringMatcher { prefix : "XYZ-016A-IXB-" , right : orStringMatcher { & literalPrefixInsensitiveStringMatcher { prefix : "DP" , right : anyS tringWitho utNewlin eMatcher{ } } , & literalPrefixInsensitiveStringMatcher { prefix : "OP" , right : anyS tringWitho utNewlin eMatcher{ } } } } } ,
{ "(?i:(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*))" , & literalPrefixInsensitiveStringMatcher { prefix : "XYZ-016A-IXB-" , right : orStringMatcher { & literalPrefixInsensitiveStringMatcher { prefix : "DP" , right : trueMatcher { } } , & literalPrefixInsensitiveStringMatcher { prefix : "OP" , right : trueMatcher { } } } } } ,
{ "(?i)(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*)" , & literalPrefixInsensitiveStringMatcher { prefix : "XYZ-016A-IXB-" , right : orStringMatcher { & literalPrefixInsensitiveStringMatcher { prefix : "DP" , right : trueMatcher { } } , & literalPrefixInsensitiveStringMatcher { prefix : "OP" , right : trueMatcher { } } } } } ,
// Concatenated variable length selectors are not supported.
{ "foo.*.*" , nil } ,
{ "foo.+.+" , nil } ,
@ -410,15 +410,15 @@ func TestStringMatcherFromRegexp(t *testing.T) {
{ "aaa.?.?" , nil } ,
{ "aaa.?.*" , nil } ,
// Regexps with ".?".
{ "ext.?|xfs" , orStringMatcher { & literalPrefixSensitiveStringMatcher { prefix : "ext" , right : & zeroOrOneCharacterStringMatcher { matchNL : fals e} } , & equalStringMatcher { s : "xfs" , caseSensitive : true } } } ,
{ "ext.?|xfs" , orStringMatcher { & literalPrefixSensitiveStringMatcher { prefix : "ext" , right : & zeroOrOneCharacterStringMatcher { matchNL : tru e} } , & equalStringMatcher { s : "xfs" , caseSensitive : true } } } ,
{ "(?s)(ext.?|xfs)" , orStringMatcher { & literalPrefixSensitiveStringMatcher { prefix : "ext" , right : & zeroOrOneCharacterStringMatcher { matchNL : true } } , & equalStringMatcher { s : "xfs" , caseSensitive : true } } } ,
{ "foo.?" , & literalPrefixSensitiveStringMatcher { prefix : "foo" , right : & zeroOrOneCharacterStringMatcher { matchNL : fals e} } } ,
{ "foo.?" , & literalPrefixSensitiveStringMatcher { prefix : "foo" , right : & zeroOrOneCharacterStringMatcher { matchNL : tru e} } } ,
{ "f.?o" , nil } ,
} {
c := c
t . Run ( c . pattern , func ( t * testing . T ) {
t . Parallel ( )
parsed , err := syntax . Parse ( c . pattern , syntax . Perl )
parsed , err := syntax . Parse ( c . pattern , syntax . Perl | syntax . DotNL )
require . NoError ( t , err )
matches := stringMatcherFromRegexp ( parsed )
require . Equal ( t , c . exp , matches )
@ -437,16 +437,16 @@ func TestStringMatcherFromRegexp_LiteralPrefix(t *testing.T) {
{
pattern : "(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*)" ,
expectedLiteralPrefixMatchers : 3 ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "xyz-016a-ixb-dpXXX" , "xyz-016a-ixb-op" , "xyz-016a-ixb-opXXX" } ,
expectedNotMatches : [ ] string { "XYZ-016a-ixb-dp" , "xyz-016a-ixb-d" , "XYZ-016a-ixb-op" , "xyz-016a-ixb-o" , "xyz" , "dp" , "xyz-016a-ixb-dp\n" } ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "xyz-016a-ixb-dpXXX" , "xyz-016a-ixb-op" , "xyz-016a-ixb-opXXX" , "xyz-016a-ixb-dp\n" } ,
expectedNotMatches : [ ] string { "XYZ-016a-ixb-dp" , "xyz-016a-ixb-d" , "XYZ-016a-ixb-op" , "xyz-016a-ixb-o" , "xyz" , "dp" } ,
} ,
// Case insensitive.
{
pattern : "(?i)(xyz-016a-ixb-dp.*|xyz-016a-ixb-op.*)" ,
expectedLiteralPrefixMatchers : 3 ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "XYZ-016a-ixb-dpXXX" , "xyz-016a-ixb-op" , "XYZ-016a-ixb-opXXX" } ,
expectedNotMatches : [ ] string { "xyz-016a-ixb-d" , "xyz" , "dp" , "xyz-016a-ixb-dp\n" } ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "XYZ-016a-ixb-dpXXX" , "xyz-016a-ixb-op" , "XYZ-016a-ixb-opXXX" , "xyz-016a-ixb-dp\n" } ,
expectedNotMatches : [ ] string { "xyz-016a-ixb-d" , "xyz" , "dp" } ,
} ,
// Nested literal prefixes, case sensitive.
@ -474,13 +474,13 @@ func TestStringMatcherFromRegexp_LiteralPrefix(t *testing.T) {
} ,
} {
t . Run ( c . pattern , func ( t * testing . T ) {
parsed , err := syntax . Parse ( c . pattern , syntax . Perl )
parsed , err := syntax . Parse ( c . pattern , syntax . Perl | syntax . DotNL )
require . NoError ( t , err )
matcher := stringMatcherFromRegexp ( parsed )
require . NotNil ( t , matcher )
re := regexp . MustCompile ( "^" + c . pattern + "$" )
re := regexp . MustCompile ( "^(?s: " + c . pattern + ") $" )
// Pre-condition check: ensure it contains literalPrefixSensitiveStringMatcher or literalPrefixInsensitiveStringMatcher.
numPrefixMatchers := 0
@ -523,16 +523,16 @@ func TestStringMatcherFromRegexp_LiteralSuffix(t *testing.T) {
{
pattern : "(.*xyz-016a-ixb-dp|.*xyz-016a-ixb-op)" ,
expectedLiteralSuffixMatchers : 2 ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "XXXxyz-016a-ixb-dp" , "xyz-016a-ixb-op" , "XXXxyz-016a-ixb-op" } ,
expectedNotMatches : [ ] string { "XYZ-016a-ixb-dp" , "yz-016a-ixb-dp" , "XYZ-016a-ixb-op" , "xyz-016a-ixb-o" , "xyz" , "dp" , "\nxyz-016a-ixb-dp" } ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "XXXxyz-016a-ixb-dp" , "xyz-016a-ixb-op" , "XXXxyz-016a-ixb-op" , "\nxyz-016a-ixb-dp" } ,
expectedNotMatches : [ ] string { "XYZ-016a-ixb-dp" , "yz-016a-ixb-dp" , "XYZ-016a-ixb-op" , "xyz-016a-ixb-o" , "xyz" , "dp" } ,
} ,
// Case insensitive.
{
pattern : "(?i)(.*xyz-016a-ixb-dp|.*xyz-016a-ixb-op)" ,
expectedLiteralSuffixMatchers : 2 ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "XYZ-016a-ixb-dp" , "XXXxyz-016a-ixb-dp" , "XyZ-016a-ixb-op" , "XXXxyz-016a-ixb-op" } ,
expectedNotMatches : [ ] string { "yz-016a-ixb-dp" , "xyz-016a-ixb-o" , "xyz" , "dp" , "\nxyz-016a-ixb-dp" } ,
expectedMatches : [ ] string { "xyz-016a-ixb-dp" , "XYZ-016a-ixb-dp" , "XXXxyz-016a-ixb-dp" , "XyZ-016a-ixb-op" , "XXXxyz-016a-ixb-op" , "\nxyz-016a-ixb-dp" } ,
expectedNotMatches : [ ] string { "yz-016a-ixb-dp" , "xyz-016a-ixb-o" , "xyz" , "dp" } ,
} ,
// Nested literal suffixes, case sensitive.
@ -552,13 +552,13 @@ func TestStringMatcherFromRegexp_LiteralSuffix(t *testing.T) {
} ,
} {
t . Run ( c . pattern , func ( t * testing . T ) {
parsed , err := syntax . Parse ( c . pattern , syntax . Perl )
parsed , err := syntax . Parse ( c . pattern , syntax . Perl | syntax . DotNL )
require . NoError ( t , err )
matcher := stringMatcherFromRegexp ( parsed )
require . NotNil ( t , matcher )
re := regexp . MustCompile ( "^" + c . pattern + "$" )
re := regexp . MustCompile ( "^(?s: " + c . pattern + ") $" )
// Pre-condition check: ensure it contains literalSuffixStringMatcher.
numSuffixMatchers := 0
@ -598,26 +598,26 @@ func TestStringMatcherFromRegexp_Quest(t *testing.T) {
{
pattern : "test.?" ,
expectedZeroOrOneMatchers : 1 ,
expectedMatches : [ ] string { "test" , "test!" } ,
expectedNotMatches : [ ] string { "test\n" , "tes " , "test!!" } ,
expectedMatches : [ ] string { "test\n" , "test " , "test!" } ,
expectedNotMatches : [ ] string { "tes" , "test!!" } ,
} ,
{
pattern : ".?test" ,
expectedZeroOrOneMatchers : 1 ,
expectedMatches : [ ] string { "test" , "!test" } ,
expectedNotMatches : [ ] string { "\ntest" , " tes" , "test!" } ,
expectedMatches : [ ] string { "\ntest" , " test" , "!test" } ,
expectedNotMatches : [ ] string { "tes" , "test!" } ,
} ,
{
pattern : "(aaa.?|bbb.?)" ,
expectedZeroOrOneMatchers : 2 ,
expectedMatches : [ ] string { "aaa" , "aaaX" , "bbb" , "bbbX" } ,
expectedNotMatches : [ ] string { "aa" , "aaaXX" , "aaa\n" , " bb" , "bbbXX" , "bbb\n " } ,
expectedMatches : [ ] string { "aaa" , "aaaX" , "bbb" , "bbbX" , "aaa\n" , "bbb\n" } ,
expectedNotMatches : [ ] string { "aa" , "aaaXX" , "bb" , "bbbXX" } ,
} ,
{
pattern : ".*aaa.?" ,
expectedZeroOrOneMatchers : 1 ,
expectedMatches : [ ] string { "aaa" , "Xaaa" , "aaaX" , "XXXaaa" , "XXXaaaX" } ,
expectedNotMatches : [ ] string { "aa" , "aaaXX" , "XXXaaaXXX" , "XXXaaa\n" } ,
expectedMatches : [ ] string { "aaa" , "Xaaa" , "aaaX" , "XXXaaa" , "XXXaaaX" , "XXXaaa\n" } ,
expectedNotMatches : [ ] string { "aa" , "aaaXX" , "XXXaaaXXX" } ,
} ,
// Match newline.
@ -632,18 +632,18 @@ func TestStringMatcherFromRegexp_Quest(t *testing.T) {
{
pattern : "(aaa.?|((?s).?bbb.+))" ,
expectedZeroOrOneMatchers : 2 ,
expectedMatches : [ ] string { "aaa" , "aaaX" , "bbbX" , "XbbbX" , "bbbXXX" , "\nbbbX" } ,
expectedNotMatches : [ ] string { "aa" , "aaa\n" , " Xbbb" , "\nbbb" } ,
expectedMatches : [ ] string { "aaa" , "aaaX" , "bbbX" , "XbbbX" , "bbbXXX" , "\nbbbX" , "aaa\n" } ,
expectedNotMatches : [ ] string { "aa" , "Xbbb" , "\nbbb" } ,
} ,
} {
t . Run ( c . pattern , func ( t * testing . T ) {
parsed , err := syntax . Parse ( c . pattern , syntax . Perl )
parsed , err := syntax . Parse ( c . pattern , syntax . Perl | syntax . DotNL )
require . NoError ( t , err )
matcher := stringMatcherFromRegexp ( parsed )
require . NotNil ( t , matcher )
re := regexp . MustCompile ( "^" + c . pattern + "$" )
re := regexp . MustCompile ( "^(?s: " + c . pattern + ") $" )
// Pre-condition check: ensure it contains zeroOrOneCharacterStringMatcher.
numZeroOrOneMatchers := 0
@ -1112,7 +1112,7 @@ func BenchmarkOptimizeEqualOrPrefixStringMatchers(b *testing.B) {
}
b . Logf ( "regexp: %s" , re )
parsed , err := syntax . Parse ( re , syntax . Perl )
parsed , err := syntax . Parse ( re , syntax . Perl | syntax . DotNL )
require . NoError ( b , err )
unoptimized := stringMatcherFromRegexpInternal ( parsed )