diff --git a/main.go b/main.go index 9926ae9..7cdb3f8 100644 --- a/main.go +++ b/main.go @@ -507,6 +507,7 @@ func main() { multiLineFlag := flag.Bool("t", false, "Multi-line mode. Treats newline just like any character.") printMatchesFlag := flag.Bool("p", false, "Prints start and end index of each match. Can only be used with '-t' for multi-line mode.") caseInsensitiveFlag = flag.Bool("i", false, "Case-insensitive. Disregard the case of all characters.") + substituteText := flag.String("s", "", "Substitute the contents of each match with the given string. Overrides -o and -v") flag.Parse() // In multi-line mode, 'dot' metacharacter also matches newline @@ -519,6 +520,13 @@ func main() { if *onlyFlag { *lineFlag = false } + // Check if substitute text has been enabled + substituteFlagEnabled := false + flag.Visit(func(f *flag.Flag) { + if f.Name == "s" { + substituteFlagEnabled = true + } + }) // Process: // 1. Convert regex into postfix notation (Shunting-Yard algorithm) @@ -607,21 +615,45 @@ func main() { continue } } - for i, c := range test_runes { - if indicesToPrint.contains(i) { - color.New(color.FgRed).Fprintf(out, "%c", c) - // Newline after every match - only if -o is enabled and -v is disabled. - if *onlyFlag && !(*invertFlag) { - for _, idx := range matchIndices { - if i+1 == idx.endIdx { // End index is one more than last index of match - fmt.Fprintf(out, "\n") - break - } + + // If we are substituting, we need a different behavior, as follows: + // For every character in the test string: + // 1. Check if the index is the start of any matchIndex + // 2. If so, print the substitute text, and set our index to + // the corresponding end index. + // 3. If not, just print the character. + if substituteFlagEnabled { + for i := range test_runes { + inMatchIndex := false + for _, idx := range matchIndices { + if i == idx.startIdx { + fmt.Fprintf(out, "%s", *substituteText) + i = idx.endIdx + inMatchIndex = true + break } } - } else { - if !(*onlyFlag) { - fmt.Fprintf(out, "%c", c) + if !inMatchIndex { + fmt.Fprintf(out, "%c", test_runes[i]) + } + } + } else { + for i, c := range test_runes { + if indicesToPrint.contains(i) { + color.New(color.FgRed).Fprintf(out, "%c", c) + // Newline after every match - only if -o is enabled and -v is disabled. + if *onlyFlag && !(*invertFlag) { + for _, idx := range matchIndices { + if i+1 == idx.endIdx { // End index is one more than last index of match + fmt.Fprintf(out, "\n") + break + } + } + } + } else { + if !(*onlyFlag) { + fmt.Fprintf(out, "%c", c) + } } } }