Sha256: 826d314d9f1c3f2ea1f6328fb37a32e747b4867c31d07e2feea758d121b8bf8c

Contents?: true

Size: 1.83 KB

Versions: 11

Compression:

Stored size: 1.83 KB

Contents

module RegexpExamples
  # A helper class to fill-in backrefences AFTER the example(s) have been generated.
  # In a nutshell, this works by doing the following:
  # * Given a regex that contains a capute group and backreference, e.g. `/(a|b) \1/`
  # * After generating examples, the backreference is tored as a placeholder:
  #   `["a __1__", "b __1__"]`
  # * This class is used to fill in each placeholder accordingly:
  #   `["a a", "b b"]`
  # * Also, beware of octal groups and cases where the backref invalidates the example!!
  class BackReferenceReplacer
    # Named capture groups can only contain alphanumeric chars, and hyphens
    PLACEHOLDER_REGEX = Regexp.new(
      RegexpExamples::BackReferenceGroup::PLACEHOLDER_FORMAT % '([a-zA-Z0-9-]+)'
    )

    def substitute_backreferences(full_examples)
      full_examples.map do |full_example|
        # For instance, one "full example" from /(a|(b)) \2/: "a __2__"
        # should be rejected because the backref (\2) does not exist
        catch(:backref_not_found) do
          substitute_backrefs_one_at_a_time(full_example)
        end
      end.compact
    end

    private

    def substitute_backrefs_one_at_a_time(full_example)
      while full_example.match(PLACEHOLDER_REGEX)
        full_example.sub!(
          PLACEHOLDER_REGEX,
          find_backref_for(full_example, Regexp.last_match(1))
        )
      end
      full_example
    end

    def find_backref_for(full_example, group_id)
      full_example.all_subgroups.detect do |subgroup|
        subgroup.group_id == group_id
      end || octal_char_for(group_id)
    end

    def octal_char_for(octal_chars)
      # For octal characters in the range \00 - \177
      if octal_chars =~ /\A[01]?[0-7]{1,2}\z/ && octal_chars.length > 1
        Integer(octal_chars, 8).chr
      else
        throw :backref_not_found
      end
    end
  end
end

Version data entries

11 entries across 11 versions & 1 rubygems

Version Path
regexp-examples-1.4.4 lib/regexp-examples/backreferences.rb
regexp-examples-1.4.3 lib/regexp-examples/backreferences.rb
regexp-examples-1.4.2 lib/regexp-examples/backreferences.rb
regexp-examples-1.4.1 lib/regexp-examples/backreferences.rb
regexp-examples-1.4.0 lib/regexp-examples/backreferences.rb
regexp-examples-1.3.2 lib/regexp-examples/backreferences.rb
regexp-examples-1.3.1 lib/regexp-examples/backreferences.rb
regexp-examples-1.3.0 lib/regexp-examples/backreferences.rb
regexp-examples-1.2.1 lib/regexp-examples/backreferences.rb
regexp-examples-1.2.0 lib/regexp-examples/backreferences.rb
regexp-examples-1.1.4 lib/regexp-examples/backreferences.rb