Created
January 14, 2014 01:15
-
-
Save jemc/8411284 to your computer and use it in GitHub Desktop.
Reverse usage of Regexp named captures to generate strings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'regexp_parser' | |
require 'pry' | |
require 'pp' | |
regexp = /foo: (?<val>\d+)?\W{0,5}(?<other>\w+)/ | |
filldata = {val: 88.99, other:"dog"} | |
class Regexp | |
def fill(filldata, tree:nil) | |
tree = Regexp::Parser.parse(self.to_s, 'ruby/1.9') if tree.nil? | |
tree.expressions.map! do |expr| | |
# Operate recursively - depth first | |
fill(filldata, tree:expr) | |
# Calculate the number of repetitions by quantifier | |
# (Gravitate toward a quantity of 1) | |
quant = expr.quantifier | |
quant = case quant.token | |
when :zero_or_one; 1 | |
when :zero_or_more; 1 | |
when :one_or_more; 1 | |
when :interval; [[quant.min,1].max, quant.max].min | |
else; 1 | |
end if quant | |
quant ||= 1 | |
# Convert the node into a matching string, | |
# using the filldata for capture groups and | |
# choosing the most basic string to satisfy other non-literals | |
# Not all cases are accounted for yet... | |
case expr | |
when Regexp::Expression::Literal; expr.to_s * quant | |
when Regexp::Expression::CharacterType::Any; "_" * quant | |
when Regexp::Expression::CharacterType::Space; " " * quant | |
when Regexp::Expression::CharacterType::NonSpace; "_" * quant | |
when Regexp::Expression::CharacterType::Digit; "0" * quant | |
when Regexp::Expression::CharacterType::NonDigit; " " * quant | |
when Regexp::Expression::CharacterType::Hex; "F" * quant | |
when Regexp::Expression::CharacterType::NonHex; " " * quant | |
when Regexp::Expression::CharacterType::Word; "x" * quant | |
when Regexp::Expression::CharacterType::NonWord; " " * quant | |
when Regexp::Expression::Group::Named | |
key = expr.text[3..-2].to_sym | |
filldata[key].to_s | |
when Regexp::Expression::Group::Options | |
expr.expressions.map(&:to_s).join # ignore options and return content | |
else; expr | |
end | |
end.first | |
end | |
end | |
# pp Regexp::Parser.parse(regexp.to_s, 'ruby/1.9') | |
pp regexp.fill(filldata) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment