matchdata-highlight
A small gem that adds a highlight method to regex match results (Ruby’s MatchData). It returns a string with marker strings inserted around the matched portion. If you omit the markers, ANSI escape sequences from term/ansicolor are used, so the match shows up in red in the terminal.
The library itself is a single file of about 40 lines, with usage examples left as comments at the end of the source.
puts "foobar foobar BAZ".match(/(foobar)/).highlight
puts /foobar/.match("foobar foobar BAZ").highlight("<B>", "</B>")
puts /foobar/.highlight("foobar foobar BAZ")
puts /foobar/.highlight("foobar foobar BAZ", :begin => '<B>', :end => '</B>')
puts /foobar/.highlight("foobar foobar BAZ", '<B>', '</B>')
Internals
It consists of nothing but monkey patches to two classes, MatchData and Regexp. Here is the processing flow.
- MatchData#highlight — the entry point, which only inspects the shape of the arguments. No arguments or a Hash passes through as-is; two positional arguments are repacked into
{:begin => args[0], :end => args[1]}and passed to_highlight - MatchData#_highlight — the real implementation. The marker defaults are
Term::ANSIColor.redfor:beginandTerm::ANSIColor.clearfor:end, overridden bymerge-ing in the options passed - Markers are inserted by
dup-ing the target string (MatchData#string) and doing a zero-width assignment at the match start position:buf[self.begin(0), 0] = marker_begin. The end marker’s insertion position isself.end(0) + marker_begin.size, shifted back by the length of the start marker inserted earlier - Positions use
begin(0)/end(0), i.e. only the whole match is targeted; it does not highlight capture groups individually or highlight multiple matches at once - Regexp#highlight(target, *args) — tries
self.match(target); on a match it delegates toMatchData#highlight, and on no match it returnstargetunchanged. You always get a string back regardless of whether there was a match - The gem scaffolding is a jeweler-generated skeleton (the gemspec is generated from the Rakefile, version 0.1.0). The README is still the skeleton, and the shoulda test skeleton remains as well