lib/regexp-examples/parser.rb in regexp-examples-0.0.2 vs lib/regexp-examples/parser.rb in regexp-examples-0.1.0

- old
+ new

@@ -43,12 +43,16 @@ end def parse_after_backslash_group @current_position += 1 case - when regexp_string[@current_position..-1] =~ /^(\d+)/ - group = parse_backreference_group($&) + when rest_of_string =~ /\A(\d+)/ + @current_position += ($1.length - 1) # In case of 10+ backrefs! + group = parse_backreference_group($1) + when rest_of_string =~ /\Ak<([^>]+)>/ # Named capture group + @current_position += ($1.length + 2) + group = parse_backreference_group($1) when BackslashCharMap.keys.include?(regexp_string[@current_position]) group = CharGroup.new( BackslashCharMap[regexp_string[@current_position]]) # TODO: There are also a bunch of multi-char matches to watch out for: # http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Literals @@ -77,15 +81,29 @@ end def parse_multi_group @current_position += 1 @num_groups += 1 - this_group_num = @num_groups + group_id = nil # init + rest_of_string.match(/\A(\?)?(:|!|=|<(!|=|[^!=][^>]*))?/) do |match| + case + when match[1].nil? # e.g. /(normal)/ + group_id = @num_groups.to_s + when match[2] == ':' # e.g. /(?:nocapture)/ + @current_position += 2 + group_id = nil + when %w(! =).include?(match[2]) # e.g. /(?=lookahead)/, /(?!neglookahead)/ + # TODO: Raise exception + when %w(! =).include?(match[3]) # e.g. /(?<=lookbehind)/, /(?<!neglookbehind)/ + # TODO: Raise exception + else # e.g. /(?<name>namedgroup)/ + @current_position += (match[3].length + 3) + group_id = match[3] + end + end groups = parse - # TODO: Non-capture groups, i.e. /...(?:foo).../ - # TODO: Named capture groups, i.e. /...(?<name>foo).../ - MultiGroup.new(groups, this_group_num) + MultiGroup.new(groups, group_id) end def parse_multi_end_group MultiGroupEnd.new end @@ -125,11 +143,11 @@ def parse_single_char_group(char) SingleCharGroup.new(char) end def parse_backreference_group(match) - BackReferenceGroup.new(match.to_i) + BackReferenceGroup.new(match) end def parse_star_repeater(group) @current_position += 1 StarRepeater.new(group) @@ -144,19 +162,23 @@ @current_position += 1 QuestionMarkRepeater.new(group) end def parse_range_repeater(group) - match = regexp_string[@current_position..-1].match(/^\{(\d+)(,)?(\d+)?\}/) + match = rest_of_string.match(/\A\{(\d+)(,)?(\d+)?\}/) @current_position += match[0].size min = match[1].to_i if match[1] has_comma = !match[2].nil? max = match[3].to_i if match[3] RangeRepeater.new(group, min, has_comma, max) end def parse_one_time_repeater(group) OneTimeRepeater.new(group) + end + + def rest_of_string + regexp_string[@current_position..-1] end end end