Added flag to print match indices, and to enable multi-line mode
This commit is contained in:
49
main.go
49
main.go
@@ -126,7 +126,7 @@ func shuntingYard(re string) []postfixNode {
|
|||||||
6. If current character is '{', find the appropriate numeric specifier (range start, range end). Apply the range to the postfixNode at the end of outQueue.
|
6. If current character is '{', find the appropriate numeric specifier (range start, range end). Apply the range to the postfixNode at the end of outQueue.
|
||||||
*/
|
*/
|
||||||
c := re_postfix[i]
|
c := re_postfix[i]
|
||||||
if isAlphaNum(c) {
|
if isNormalChar(c) {
|
||||||
outQueue = append(outQueue, newPostfixNode(c))
|
outQueue = append(outQueue, newPostfixNode(c))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,9 @@ func main() {
|
|||||||
// 1. Without '-v': Prints only matches. Prints a newline after every match.
|
// 1. Without '-v': Prints only matches. Prints a newline after every match.
|
||||||
// 2. With '-v': Substitutes all matches with empty string.
|
// 2. With '-v': Substitutes all matches with empty string.
|
||||||
onlyFlag := flag.Bool("o", false, "Print only colored content. Overrides -l.")
|
onlyFlag := flag.Bool("o", false, "Print only colored content. Overrides -l.")
|
||||||
lineFlag := flag.Bool("l", false, "Only print lines with a match (or with no matches, if -v is enabled")
|
lineFlag := flag.Bool("l", false, "Only print lines with a match (or with no matches, if -v is enabled (similar to grep's default")
|
||||||
|
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.")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// -l and -o are mutually exclusive: -o overrides -l
|
// -l and -o are mutually exclusive: -o overrides -l
|
||||||
@@ -402,16 +404,50 @@ func main() {
|
|||||||
var test_str string
|
var test_str string
|
||||||
var test_runes []rune // Rune-slice representation of test_str
|
var test_runes []rune // Rune-slice representation of test_str
|
||||||
var err error
|
var err error
|
||||||
// Create reader for stdin and writer for stdout // End index is one more than last index of match
|
var linesRead bool // Whether or not we have read the lines in the file
|
||||||
|
// Create reader for stdin and writer for stdout
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
out := bufio.NewWriter(os.Stdout)
|
out := bufio.NewWriter(os.Stdout)
|
||||||
|
|
||||||
re_postfix := shuntingYard(re)
|
re_postfix := shuntingYard(re)
|
||||||
startState := thompson(re_postfix)
|
startState := thompson(re_postfix)
|
||||||
// Read every string from stdin until we encounter an error. If the error isn't EOF, panic.'
|
for true {
|
||||||
for test_str, err = reader.ReadString('\n'); err == nil; test_str, err = reader.ReadString('\n') {
|
if linesRead {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !(*multiLineFLag) {
|
||||||
|
// Read every string from stdin until we encounter an error. If the error isn't EOF, panic.
|
||||||
|
test_str, err = reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
linesRead = true
|
||||||
|
} else {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Multi-line mode - read every line of input into a temp. string.
|
||||||
|
// test_str will contain all lines of input (including newline characters)
|
||||||
|
// as one string.
|
||||||
|
var temp string
|
||||||
|
for temp, err = reader.ReadString('\n'); err == nil; temp, err = reader.ReadString('\n') {
|
||||||
|
test_str += temp
|
||||||
|
}
|
||||||
|
// Assuming err != nil
|
||||||
|
if err == io.EOF {
|
||||||
|
linesRead = true
|
||||||
|
} else {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
test_runes = []rune(test_str)
|
test_runes = []rune(test_str)
|
||||||
matchIndices := findAllMatches(startState, []rune(test_runes))
|
matchIndices := findAllMatches(startState, []rune(test_runes))
|
||||||
|
if *printMatchesFlag {
|
||||||
|
for _, idx := range matchIndices {
|
||||||
|
fmt.Printf("%s\n", idx.toString())
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
// Decompose the array of matchIndex structs into a flat unique array of ints - if matchIndex is {4,7}, flat array will contain 4,5,6
|
// Decompose the array of matchIndex structs into a flat unique array of ints - if matchIndex is {4,7}, flat array will contain 4,5,6
|
||||||
// This should make checking O(1) instead of O(n)
|
// This should make checking O(1) instead of O(n)
|
||||||
indicesToPrint := new_uniq_arr[int]()
|
indicesToPrint := new_uniq_arr[int]()
|
||||||
@@ -463,7 +499,4 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != io.EOF {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user