Regex Tester — Ruby source
Test regular expressions against any text with all flags (g/i/m/s/u/y). See every match, its index and capture groups, plus the constructed pattern. 100% in-browser.
This is the Ruby implementation — the same logic the interactive tool runs, in a shareable, citable form.
# regex-tester — Ruby port. Match a pattern against text, report every match
# with capture groups and index (Regexp + match-with-position loop).
RegexMatch = Struct.new(:match, :index, :groups)
# JS flag letters -> Regexp constants. Ruby's ^/$ are always line-anchored
# (JS `m` is permanently on); `s` maps to Regexp::MULTILINE (dotall); `u` is
# the default for UTF-8 strings; `y` has no equivalent.
def compile_options(flags)
opts = 0
opts |= Regexp::IGNORECASE if flags.include?('i')
opts |= Regexp::MULTILINE if flags.include?('s')
opts
end
def run_regex(pattern, flags, text)
re = Regexp.new(pattern, compile_options(flags))
limit = flags.include?('g') ? 2000 : 1
out = []
pos = 0
while out.size < limit && (m = re.match(text, pos))
out << RegexMatch.new(m[0], m.begin(0), m.captures.map { |g| g || '' })
pos = m.end(0) + (m.end(0) == m.begin(0) ? 1 : 0) # advance past zero-width
break if pos > text.length
end
out
rescue RegexpError => e
warn "error: #{e.message}"
[]
end
# Render a result the way the tool's UI does:
# `N. "match" @ index -> [g1, g2]`, or `(none)` when empty.
def format_matches(matches)
return '(none)' if matches.empty?
matches.each_with_index.map do |m, i|
line = %(#{i + 1}. "#{m.match}" @ #{m.index})
line += " → [#{m.groups.join(', ')}]" unless m.groups.empty?
line
end.join("\n")
end
puts format_matches(run_regex(/(\w+)@(\w+)\.(\w+)/, 'g', 'mail@x.com nope bob@test.org'))
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →