diff --git a/.golangci.yml b/.golangci.yml index 203106e..319ffa1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -68,7 +68,7 @@ output: print-linter-name: true # make issues output unique by line, default is true - #uniq-by-line: true + uniq-by-line: false # add a prefix to the output file references; default is no prefix path-prefix: "" @@ -352,6 +352,7 @@ linters-settings: - github.com/stretchr/testify domains: # List of allowed module domains - golang.org + - code.bcarlin.xyz blocked: modules: # List of blocked modules # - github.com/uudashr/go-module: # Blocked module @@ -362,7 +363,7 @@ linters-settings: # - github.com/mitchellh/go-homedir: # Blocked module with version constraint # version: "< 1.1.0" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons # reason: "testing if blocked version constraint works." # Reason why the version constraint exists. (Optional) - local_replace_directives: false # Set to true to raise lint issues for packages that are loaded from a local path via replace directive + local_replace_directives: true # Set to true to raise lint issues for packages that are loaded from a local path via replace directive gosec: # To select a subset of rules to run. @@ -411,7 +412,7 @@ linters-settings: # run `go tool vet help` to see all analyzers #enable: # - atomicalign - #enable-all: false + enable-all: false #disable: # - shadow #disable-all: false @@ -450,10 +451,12 @@ linters-settings: # alias: $1$2 lll: - # max line length, lines longer will be reported. Default is 120. - # '\t' is counted as 1 character by default, and can be changed with the tab-width option - line-length: 100 - # tab width in spaces. Default to 1. + # Max line length, lines longer will be reported. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option. + # Default: 120. + line-length: 90 + # Tab width in spaces. + # Default: 1 tab-width: 1 makezero: @@ -525,19 +528,336 @@ linters-settings: - github.com/jmoiron/modl revive: - # see https://github.com/mgechev/revive#available-rules for details. + # Maximum number of open files at the same time. + # See https://github.com/mgechev/revive#command-line-flags + # Defaults to unlimited. + #max-open-files: 2048 + # When set to false, ignores files with "GENERATED" header, similar to golint. + # See https://github.com/mgechev/revive#available-rules for details. + # Default: false ignore-generated-header: true + # Sets the default severity. + # See https://github.com/mgechev/revive#configuration + # Default: warning severity: warning - #rules: - # - name: indent-error-flow - # severity: warning - # - name: add-constant - # severity: warning - # arguments: - # - maxLitCount: "3" - # allowStrs: '""' - # allowInts: "0,1,2" - # allowFloats: "0.0,0.,1.0,1.,2.0,2." + # Enable all available rules. + # Default: false + enable-all-rules: true + # Sets the default failure confidence. + # This means that linting errors with less than 0.8 confidence will be ignored. + # Default: 0.8 + #confidence: 0.1 + rules: + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#add-constant + - name: add-constant + severity: warning + disabled: false + arguments: + - maxLitCount: "3" + allowStrs: '""' + allowInts: "0,1" + allowFloats: "" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#atomic + - name: argument-limit + severity: warning + disabled: false + arguments: [4] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#atomic + - name: atomic + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#banned-characters + - name: banned-characters + severity: warning + disabled: true + arguments: ["Ω", "Σ", "σ", "7"] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bare-return + - name: bare-return + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#blank-imports + - name: blank-imports + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr + - name: bool-literal-in-expr + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#call-to-gc + - name: call-to-gc + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cognitive-complexity + - name: cognitive-complexity + severity: warning + disabled: false + arguments: [7] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-naming + - name: confusing-naming + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-results + - name: confusing-results + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#constant-logical-expr + - name: constant-logical-expr + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument + - name: context-as-argument + severity: info + disabled: false + arguments: + - allowTypesBefore: "*testing.T" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-keys-type + - name: context-keys-type + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cyclomatic + - name: cyclomatic + severity: error + disabled: false + arguments: [20] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#deep-exit + - name: deep-exit + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#defer + - name: defer + severity: error + disabled: false + #arguments: + # - ["call-chain", "loop"] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#dot-imports + - name: dot-imports + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports + - name: duplicated-imports + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return + - name: early-return + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block + - name: empty-block + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines + - name: empty-lines + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-naming + - name: error-naming + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-return + - name: error-return + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-strings + - name: error-strings + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#errorf + - name: errorf + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#exported + - name: exported + severity: warning + disabled: false + arguments: + - "checkPrivateReceivers" + - "sayRepetitiveInsteadOfStutters" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#file-header + - name: file-header + severity: warning + disabled: true + arguments: + - This is the text that must appear at the top of source files. + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#flag-parameter + - name: flag-parameter + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-result-limit + - name: function-result-limit + severity: warning + disabled: false + arguments: [2] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-length + - name: function-length + severity: warning + disabled: false + arguments: [20, 0] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#get-return + - name: get-return + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#identical-branches + - name: identical-branches + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#if-return + - name: if-return + severity: warning + disabled: true + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#increment-decrement + - name: increment-decrement + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow + - name: indent-error-flow + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#imports-blacklist + - name: imports-blacklist + severity: warning + disabled: false + arguments: + - "crypto/md5" + - "crypto/sha1" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-shadowing + - name: import-shadowing + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#line-length-limit + - name: line-length-limit + severity: info + disabled: false + arguments: [90] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#max-public-structs + - name: max-public-structs + severity: warning + disabled: false + arguments: [3] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-parameter + - name: modifies-parameter + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-value-receiver + - name: modifies-value-receiver + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#nested-structs + - name: nested-structs + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#optimize-operands-order + - name: optimize-operands-order + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments + - name: package-comments + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range + - name: range + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-in-closure + - name: range-val-in-closure + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-address + - name: range-val-address + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#receiver-naming + - name: receiver-naming + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redefines-builtin-id + - name: redefines-builtin-id + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-of-int + - name: string-of-int + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-format + - name: string-format + severity: warning + disabled: false + arguments: + - - 'fmt.Errorf[0]' + - '/(^|[^\.!?])$/' + - must not end in punctuation + - - panic + - '/^[^\n]*$/' + - must not contain line breaks + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#struct-tag + - name: struct-tag + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#superfluous-else + - name: superfluous-else + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-equal + - name: time-equal + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-naming + - name: time-naming + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-naming + - name: var-naming + severity: warning + disabled: false + arguments: + - ["ID"] # AllowList + - ["VM"] # DenyList + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-declaration + - name: var-declaration + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unconditional-recursion + - name: unconditional-recursion + severity: error + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-naming + - name: unexported-naming + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-return + - name: unexported-return + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error + - name: unhandled-error + severity: warning + disabled: false + arguments: + - "fmt.Printf" + - "myFunction" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unnecessary-stmt + - name: unnecessary-stmt + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unreachable-code + - name: unreachable-code + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter + - name: unused-parameter + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-receiver + - name: unused-receiver + severity: info + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break + - name: useless-break + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#waitgroup-by-value + - name: waitgroup-by-value + severity: warning + disabled: false staticcheck: # Select the Go version to target. The default is '1.13'. @@ -663,13 +983,15 @@ linters: - depguard - exhaustivestruct - goheader - - golint + - golint # Deprecated - interfacer + - lll # Done by revive with better messages - maligned - paralleltest - prealloc - - scopelint + - scopelint # Deprecated - testpackage + - varcheck # also done by unused and deadcode #presets: # - bugs # - unused @@ -777,12 +1099,13 @@ severity: # If set to true severity-rules regular expressions become case sensitive. case-sensitive: false - # Default value is empty list. - # When a list of severity rules are provided, severity information will be added to lint - # issues. Severity rules have the same filtering capability as exclude rules except you - # are allowed to specify one matcher per severity rule. - # Only affects out formats that support setting severity information. + # Default value is empty list. When a list of severity rules are + # provided, severity information will be added to lint issues. Severity + # rules have the same filtering capability as exclude rules except you + # are allowed to specify one matcher per severity rule. Only affects out + # formats that support setting severity information. rules: - - linters: - - dupl - severity: info + #- linters: + # - dupl + # - lll + # severity: info diff --git a/rx.go b/rx.go index fb7fe8c..0e0f9e8 100644 --- a/rx.go +++ b/rx.go @@ -6,42 +6,65 @@ import ( "strings" ) +// Flags changes the meaning of the regex. +type Flags uint + +const ( + // CaseInsensitive makes the regex case insensitive (flag "i" set). + CaseInsensitive Flags = 1 << iota + + // CaseSensitive makes the regex case sensitive (flag "i" cleared, + // default behavior). + CaseSensitive + + // MultiLine makes StartOfText and EndOfText match the beginning and + // the end of each line (flag "m" set). + MultiLine + + // SingleLine makes StartOfText and EndOfText match the beginning and + // the end of the whole text (flag "m" cleared, default behavior). + SingleLine + + // AnyNL makes Any match new lines(flag "s" set). + AnyNL + + // AnyNoNL makes Any not match new lines (flag "s" cleared, default + // behavior). + AnyNoNL + + // Ungreedy makes the quantifiers match the shortest text possible + // (flag "U" set). + Ungreedy + + // Greedy makes the quantifiers match the longest text possible (flag + // "U" cleared, default behavior). + Greedy +) + // Regex represents a regular expression. type Regex string const ( // Any matches any character ("."). - Any = "." + Any Regex = "." + + nonGreedyOp Regex = "?" ) // // CHARACTER CLASSES // -// In generates a character class composed by the concatenation of all arguments. +// In generates a character class composed by the concatenation of all +// arguments. func (r Regex) In(rxs ...Regex) Regex { - r += "[" - - for _, rx := range rxs { - r += rx - } - - r += "]" - - return r + return r + "[" + joinRxs(rxs, "") + "]" } -// NotIn generates a negated character class composed by the concatenation of all arguments. +// NotIn generates a negated character class composed by the concatenation +// of all arguments. func (r Regex) NotIn(rxs ...Regex) Regex { - r += "[^" - - for _, rx := range rxs { - r += rx - } - - r += "]" - - return r + return r + "[^" + joinRxs(rxs, "") + "]" } // @@ -50,46 +73,33 @@ func (r Regex) NotIn(rxs ...Regex) Regex { // Then appends the given regexes to the current one. func (r Regex) Then(rxs ...Regex) Regex { - for _, rx := range rxs { - r += rx - } - - return r + return r + joinRxs(rxs, "") } // AnyOf appends an alternative to the regex. The resulting alternative // matches any of the given regexes. func (r Regex) AnyOf(rxs ...Regex) Regex { - r += "(?:" - - for i, rx := range rxs { - if i != 0 { - r += "|" - } - - r += rx - } - - r += ")" - - return r + return r + "(?:" + joinRxs(rxs, "|") + ")" } // // QUANTIFIERS // -// ZeroOrMore appends the given regex with a "zero or more" quantifier ("*"), prefer more. +// ZeroOrMore appends the given regex with a "zero or more" quantifier +// ("*"), prefer more. func (r Regex) ZeroOrMore(rx Regex) Regex { return r + protectMultiChar(rx) + "*" } -// OneOrMore appends the given regex with a "one or more" quantifier ("+"), prefer more. +// OneOrMore appends the given regex with a "one or more" quantifier ("+"), +// prefer more. func (r Regex) OneOrMore(rx Regex) Regex { return r + protectMultiChar(rx) + "+" } -// ZeroOrOne appends the given regex with a "one or more" quantifier ("?"), prefer more. +// ZeroOrOne appends the given regex with a "one or more" quantifier ("?"), +// prefer more. func (r Regex) ZeroOrOne(rx Regex) Regex { return r + protectMultiChar(rx) + "?" } @@ -99,7 +109,8 @@ func (r Regex) NTimes(n int, rx Regex) Regex { return Regex(fmt.Sprintf("%s%s{%d}", r, protectMultiChar(rx), n)) } -// NOrMore appends the given regex with an minimum number of repeats ("{N,}"), prefer more. +// NOrMore appends the given regex with an minimum number of repeats +// ("{N,}"), prefer more. func (r Regex) NOrMore(n int, rx Regex) Regex { return Regex(fmt.Sprintf("%s%s{%d,}", r, protectMultiChar(rx), n)) } @@ -110,35 +121,67 @@ func (r Regex) NUpToM(n, m int, rx Regex) Regex { return Regex(fmt.Sprintf("%s%s{%d,%d}", r, protectMultiChar(rx), n, m)) } -// ZeroOrMoreLazy appends the given regex with a "zero or more" quantifier ("*"), prefer more. +// ZeroOrMoreLazy appends the given regex with a "zero or more" quantifier +// ("*"), prefer more. func (r Regex) ZeroOrMoreLazy(rx Regex) Regex { - return r.ZeroOrMore(rx) + "?" + return r.ZeroOrMore(rx) + nonGreedyOp } -// OneOrMoreLazy appends the given regex with a "one or more" quantifier ("+"), prefer more. +// OneOrMoreLazy appends the given regex with a "one or more" quantifier +// ("+"), prefer more. func (r Regex) OneOrMoreLazy(rx Regex) Regex { - return r.OneOrMore(rx) + "?" + return r.OneOrMore(rx) + nonGreedyOp } -// ZeroOrOneLazy appends the given regex with a "one or more" quantifier ("?"), prefer more. +// ZeroOrOneLazy appends the given regex with a "one or more" quantifier +// ("?"), prefer more. func (r Regex) ZeroOrOneLazy(rx Regex) Regex { - return r.ZeroOrOne(rx) + "?" + return r.ZeroOrOne(rx) + nonGreedyOp } // NTimesLazy appends the given regex with an exact number of repeats ("{N}"). func (r Regex) NTimesLazy(n int, rx Regex) Regex { - return r.NTimes(n, rx) + "?" + return r.NTimes(n, rx) + nonGreedyOp } -// NOrMoreLazy appends the given regex with an minimum number of repeats ("{N,}"), prefer more. +// NOrMoreLazy appends the given regex with an minimum number of repeats +// ("{N,}"), prefer more. func (r Regex) NOrMoreLazy(n int, rx Regex) Regex { - return r.NOrMore(n, rx) + "?" + return r.NOrMore(n, rx) + nonGreedyOp } // NUpToMLazy appends the given regex with an minimum and maximum number of repeats // ("{N,M}"), prefer more. func (r Regex) NUpToMLazy(n, m int, rx Regex) Regex { - return r.NUpToM(n, m, rx) + "?" + return r.NUpToM(n, m, rx) + nonGreedyOp +} + +// +// GROUPS +// + +// Capture appends a capture group to the regexes. The regexes given as +// arguments are just concatenated. +func (r Regex) Capture(rxs ...Regex) Regex { + return r + "(" + joinRxs(rxs, "") + ")" +} + +// CaptureName appends a named capture group to the regexes. The regexes +// given as arguments are just concatenated. +func (r Regex) CaptureName(name string, rxs ...Regex) Regex { + return r + "(?P<" + Regex(name) + ">" + joinRxs(rxs, "") + ")" +} + +// WithFlags appends a non-capturing group with the given flags set to the +// regex. The regexes given as arguments are just concatenated. +func (r Regex) WithFlags(flags Flags, rxs ...Regex) Regex { + tmp := joinRxs(rxs, "") + + if f := buildFlagString(flags); f != "" { + tmp = "(?" + Regex(f) + ":" + tmp + ")" + } + + return r + tmp } // @@ -215,3 +258,59 @@ func areHexaDigits(s string) bool { return true } + +func buildFlagString(flags Flags) string { + set, cleared := "", "" + + if flags&CaseInsensitive != 0 { + set += "i" + } + + if flags&MultiLine != 0 { + set += "m" + } + + if flags&AnyNL != 0 { + set += "s" + } + + if flags&Ungreedy != 0 { + set += "U" + } + + if flags&CaseSensitive != 0 { + cleared += "i" + } + + if flags&SingleLine != 0 { + cleared += "m" + } + + if flags&AnyNoNL != 0 { + cleared += "s" + } + + if flags&Greedy != 0 { + cleared += "U" + } + + if cleared != "" { + cleared = "-" + cleared + } + + return set + cleared +} + +func joinRxs(rxs []Regex, sep string) Regex { + var rv Regex + + for i := range rxs { + if i != 0 { + rv += Regex(sep) + } + + rv += rxs[i] + } + + return rv +} diff --git a/rx_test.go b/rx_test.go index b276ee0..99467c2 100644 --- a/rx_test.go +++ b/rx_test.go @@ -46,6 +46,31 @@ func TestRegex(t *testing.T) { require.Equal(t, tc.expected, string(a.ZeroOrMore(tc.rx))) } }) + + t.Run("WithFlags() method", func(t *testing.T) { + tcs := []struct { + rx Flags + expected string + }{ + {0, "aa"}, + {CaseInsensitive, "a(?i:a)"}, + {CaseSensitive, "a(?-i:a)"}, + {MultiLine, "a(?m:a)"}, + {SingleLine, "a(?-m:a)"}, + {AnyNL, "a(?s:a)"}, + {AnyNoNL, "a(?-s:a)"}, + {Ungreedy, "a(?U:a)"}, + {Greedy, "a(?-U:a)"}, + {CaseInsensitive | MultiLine, "a(?im:a)"}, + {CaseInsensitive | SingleLine, "a(?i-m:a)"}, + {0b11111111, "a(?imsU-imsU:a)"}, + {CaseInsensitive | MultiLine | AnyNoNL | Greedy, "a(?im-sU:a)"}, + } + + for _, tc := range tcs { + require.Equal(t, tc.expected, string(a.WithFlags(tc.rx, "a"))) + } + }) } func ExampleRegex_In() { @@ -163,3 +188,18 @@ func ExampleRegex_NUpToMLazy() { // ab{3,5}? // a(?:abc){3,5}? } + +func ExampleRegex_Capture() { + fmt.Println(Regex("a").Capture("a", "b")) + // Output: a(ab) +} + +func ExampleRegex_CaptureName() { + fmt.Println(Regex("a").CaptureName("foo", "a", "b")) + // Output: a(?Pab) +} + +func ExampleRegex_WithFlags() { + fmt.Println(Regex("a").WithFlags(AnyNL|CaseSensitive, "a", "b")) + // Output: a(?s-i:ab) +}