to-regexp-0.2.1/ 0000755 0001750 0001750 00000000000 13571230550 012451 5 ustar pravi pravi to-regexp-0.2.1/LICENSE 0000644 0001750 0001750 00000002057 13571230550 013462 0 ustar pravi pravi Copyright (c) 2013 Seamus Abshere
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
to-regexp-0.2.1/CHANGELOG 0000644 0001750 0001750 00000000632 13571230550 013664 0 ustar pravi pravi 0.2.1 / 2013-05-21
* Bug fixes
* Make sure (for example) '/foo/imn'.to_regexp(detect: true) is detected as a case-insensitive, multiline, no-encoding regexp
0.2.0 / 2013-02-13
* Breaking changes
* Strings are no longer stripped before conversion is attempted
* :detect will make '' into nil and '//' into //
0.1.2 / 2013-02-13
* Enhancements
* Start keeping CHANGELOG!
* add :detect option
to-regexp-0.2.1/Rakefile 0000644 0001750 0001750 00000000511 13571230550 014113 0 ustar pravi pravi require 'bundler'
Bundler::GemHelper.install_tasks
require 'rake'
require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
test.libs << 'lib' << 'test'
test.pattern = 'test/**/test_*.rb'
test.verbose = true
end
task :default => :test
require 'yard'
YARD::Rake::YardocTask.new do |y|
y.options << '--no-private'
end
to-regexp-0.2.1/Gemfile 0000644 0001750 0001750 00000000121 13571230550 013736 0 ustar pravi pravi source :rubygems
# Specify your gem's dependencies in to_regexp.gemspec
gemspec
to-regexp-0.2.1/.gitignore 0000644 0001750 0001750 00000000057 13571230550 014443 0 ustar pravi pravi *.gem
.bundle
Gemfile.lock
pkg/*
doc/
.yardoc/
to-regexp-0.2.1/to_regexp.gemspec 0000644 0001750 0001750 00000001600 13571230550 016007 0 ustar pravi pravi # -*- encoding: utf-8 -*-
require File.expand_path("../lib/to_regexp/version", __FILE__)
Gem::Specification.new do |s|
s.name = "to_regexp"
s.version = ToRegexp::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Seamus Abshere"]
s.email = ["seamus@abshere.net"]
s.homepage = "https://github.com/seamusabshere/to_regexp"
s.summary = %q{Provides String#to_regexp}
s.description = %q{Provides String#to_regexp, for example if you want to make regexps out of a CSV you just imported.}
s.rubyforge_project = "to_regexp"
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
s.add_development_dependency 'ensure-encoding'
s.add_development_dependency 'yard'
end
to-regexp-0.2.1/lib/ 0000755 0001750 0001750 00000000000 13571230550 013217 5 ustar pravi pravi to-regexp-0.2.1/lib/to_regexp.rb 0000644 0001750 0001750 00000005520 13571230550 015542 0 ustar pravi pravi # encoding: utf-8
module ToRegexp
module Regexp
def to_regexp
self
end
end
module String
class << self
def literal?(str)
REGEXP_DELIMITERS.none? { |s, e| str.start_with?(s) and str =~ /#{e}#{INLINE_OPTIONS}\z/ }
end
end
INLINE_OPTIONS = /[imxnesu]*/
REGEXP_DELIMITERS = {
'%r{' => '}',
'/' => '/',
}
# Get a regexp back
#
# Without :literal or :detect, `"foo".to_regexp` will return nil.
#
# @param [optional, Hash] options
# @option options [true,false] :literal Treat meta characters and other regexp codes as just text; always return a regexp
# @option options [true,false] :detect If string starts and ends with valid regexp delimiters, treat it as a regexp; otherwise, interpret it literally
# @option options [true,false] :ignore_case /foo/i
# @option options [true,false] :multiline /foo/m
# @option options [true,false] :extended /foo/x
# @option options [true,false] :lang /foo/[nesu]
def to_regexp(options = {})
if args = as_regexp(options)
::Regexp.new *args
end
end
# Return arguments that can be passed to `Regexp.new`
# @see to_regexp
def as_regexp(options = {})
unless options.is_a?(::Hash)
raise ::ArgumentError, "[to_regexp] Options must be a Hash"
end
str = self
return if options[:detect] and str == ''
if options[:literal] or (options[:detect] and ToRegexp::String.literal?(str))
content = ::Regexp.escape str
elsif delim_set = REGEXP_DELIMITERS.detect { |k, _| str.start_with?(k) }
delim_start, delim_end = delim_set
/\A#{delim_start}(.*)#{delim_end}(#{INLINE_OPTIONS})\z/u =~ str
content = $1
inline_options = $2
return unless content.is_a?(::String)
content.gsub! '\\/', '/'
if inline_options
options[:ignore_case] = true if inline_options.include?('i')
options[:multiline] = true if inline_options.include?('m')
options[:extended] = true if inline_options.include?('x')
# 'n', 'N' = none, 'e', 'E' = EUC, 's', 'S' = SJIS, 'u', 'U' = UTF-8
options[:lang] = inline_options.scan(/[nesu]/i).join.downcase
end
else
return
end
ignore_case = options[:ignore_case] ? ::Regexp::IGNORECASE : 0
multiline = options[:multiline] ? ::Regexp::MULTILINE : 0
extended = options[:extended] ? ::Regexp::EXTENDED : 0
lang = options[:lang] || ''
if ::RUBY_VERSION > '1.9' and lang.include?('u')
lang = lang.delete 'u'
end
if lang.empty?
[ content, (ignore_case|multiline|extended) ]
else
[ content, (ignore_case|multiline|extended), lang ]
end
end
end
end
::String.send :include, ::ToRegexp::String
::Regexp.send :include, ::ToRegexp::Regexp
to-regexp-0.2.1/lib/to_regexp/ 0000755 0001750 0001750 00000000000 13571230550 015213 5 ustar pravi pravi to-regexp-0.2.1/lib/to_regexp/version.rb 0000644 0001750 0001750 00000000050 13571230550 017220 0 ustar pravi pravi module ToRegexp
VERSION = '0.2.1'
end
to-regexp-0.2.1/test/ 0000755 0001750 0001750 00000000000 13571230550 013430 5 ustar pravi pravi to-regexp-0.2.1/test/helper.rb 0000644 0001750 0001750 00000000413 13571230550 015232 0 ustar pravi pravi unless RUBY_VERSION >= '1.9'
require 'rubygems'
end
require 'bundler'
Bundler.setup
require 'test/unit'
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'to_regexp'
class Test::Unit::TestCase
end
to-regexp-0.2.1/test/test_to_regexp.rb 0000644 0001750 0001750 00000015310 13571230550 017010 0 ustar pravi pravi # encoding: UTF-8
require 'helper'
class TestToRegexp < Test::Unit::TestCase
def test_000_versus_eval_ascii
str = "/finalis(e)/im"
old_way = eval(str)
new_way = str.to_regexp
assert_equal old_way, new_way
end
def test_000a_versus_eval_utf8
str = "/finalis(é)/im"
old_way = eval(str)
new_way = str.to_regexp
assert_equal old_way, new_way
end
def test_001_utf8
assert_equal 'ë', '/(ë)/'.to_regexp.match('Citroën').captures[0]
end
def test_002_multiline
assert_equal nil, '/foo.*(bar)/'.to_regexp.match("foo\n\nbar")
assert_equal 'bar', '/foo.*(bar)/m'.to_regexp.match("foo\n\nbar").captures[0]
end
def test_003_ignore_case
assert_equal nil, '/(FOO)/'.to_regexp.match('foo')
assert_equal 'foo', '/(FOO)/i'.to_regexp.match('foo').captures[0]
end
def test_004_percentage_r_notation
assert_equal '/', '%r{(/)}'.to_regexp.match('/').captures[0]
end
def test_005_multiline_and_ignore_case
assert_equal 'bar', '/FOO.*(BAR)/mi'.to_regexp.match("foo\n\nbar").captures[0]
end
def test_006_cant_fix_garbled_input
if RUBY_VERSION >= '1.9'
garbled = 'finalisé'.force_encoding('ASCII-8BIT') # like if it was misinterpreted
assert_raises(Encoding::CompatibilityError) do
'/finalis(é)/'.to_regexp.match(garbled)
end
else # not applicable to ruby 1.8
garbled = 'finalisé'
assert_nothing_raised do
'/finalis(é)/'.to_regexp.match(garbled)
end
end
end
def test_007_possible_garbled_input_fix_using_manfreds_gem
if RUBY_VERSION >= '1.9'
require 'ensure/encoding'
garbled = 'finalisé'.force_encoding('ASCII-8BIT') # like if it was misinterpreted
assert_equal 'é', '/finalis(é)/'.to_regexp.match(garbled.ensure_encoding('UTF-8')).captures[0]
else # not applicable to ruby 1.8
garbled = 'finalisé'
assert_equal 'é', '/finalis(é)/'.to_regexp.match(garbled).captures[0]
end
end
def test_008_as_regexp
str = '/finalis(é)/in'
assert_equal ['finalis(é)', ::Regexp::IGNORECASE, 'n'], str.as_regexp
assert_equal Regexp.new(*str.as_regexp), str.to_regexp
end
def test_009_ruby_19_splat
assert_equal nil, 'hi'.to_regexp
end
def test_010_regexp_to_regexp
a = /foo/
assert_equal a, a.to_regexp
end
def test_011_ignore_case_option
assert_equal nil, '/(FOO)/'.to_regexp(:ignore_case => false).match('foo')
assert_equal nil, '/(FOO)/'.to_regexp(:ignore_case => false).match('foo')
assert_equal 'foo', '/(FOO)/'.to_regexp(:ignore_case => true).match('foo').captures[0]
assert_equal 'foo', '/(FOO)/i'.to_regexp(:ignore_case => true).match('foo').captures[0]
end
def test_012_literal_option
assert '/(FOO)/'.to_regexp(:literal => true).match('hello/(FOO)/there')
end
def test_013_combine_literal_and_ignore_case
assert '/(FOO)/'.to_regexp(:literal => true, :ignore_case => true).match('hello/(foo)/there')
# can't use inline options obviously
assert_equal nil, '/(FOO)/i'.to_regexp(:literal => true).match('hello/(foo)/there')
assert '/(FOO)/i'.to_regexp(:literal => true).match('hello/(FOO)/ithere')
end
def test_014_try_convert
if RUBY_VERSION >= '1.9'
assert_equal /foo/i, Regexp.try_convert('/foo/i')
assert_equal //, Regexp.try_convert('//')
end
end
# seen in the wild - from rack-1.2.5/lib/rack/utils.rb - converted to array to preserve order in 1.8.7
ESCAPE_HTML_KEYS = [
"&",
"<",
">",
"'",
'"',
"/"
]
def test_015_union
assert_equal /penzance/, Regexp.union('penzance')
assert_equal /skiing|sledding/, Regexp.union('skiing', 'sledding')
assert_equal /skiing|sledding/, Regexp.union(['skiing', 'sledding'])
assert_equal /(?-mix:dogs)|(?i-mx:cats)/, Regexp.union(/dogs/, /cats/i)
assert_equal /(?-mix:dogs)|(?i-mx:cats)/, Regexp.union('/dogs/', /cats/i)
assert_equal /(?-mix:dogs)|(?i-mx:cats)/, Regexp.union(/dogs/, '/cats/i')
assert_equal %r{&|<|>|'|"|\/}.inspect, Regexp.union(*ESCAPE_HTML_KEYS).inspect
end
def test_016_detect
assert_equal nil, ''.to_regexp(detect: true)
assert_equal //, '//'.to_regexp(detect: true)
assert_equal /foo/, 'foo'.to_regexp(detect: true)
assert_equal %r{foo\\b}, 'foo\b'.to_regexp(detect: true)
assert_equal %r{foo\b}, '/foo\b/'.to_regexp(detect: true)
assert_equal %r{foo\\b/}, 'foo\b/'.to_regexp(detect: true)
assert_equal %r{foo\b}i, '/foo\b/i'.to_regexp(detect: true)
assert_equal %r{foo\\b/i}, 'foo\b/i'.to_regexp(detect: true)
assert_equal /FOO.*(BAR)/mi, '/FOO.*(BAR)/mi'.to_regexp(detect: true)
end
# https://github.com/ruby/ruby/blob/trunk/test/ruby/test_regexp.rb#L474 "test_union2"
def test_mri_union2
assert_equal(/(?!)/, Regexp.union)
assert_equal(/foo/, Regexp.union(/foo/))
assert_equal(/foo/, Regexp.union([/foo/]))
assert_equal(/\t/, Regexp.union("\t"))
assert_equal(/(?-mix:\u3042)|(?-mix:\u3042)/, Regexp.union(/\u3042/, /\u3042/))
assert_equal("\u3041", "\u3041"[Regexp.union(/\u3042/, "\u3041")])
end
# https://github.com/ruby/ruby/blob/trunk/test/ruby/test_regexp.rb#L464 "test_try_convert"
def test_mri_try_convert
assert_equal(/re/, Regexp.try_convert(/re/))
assert_nil(Regexp.try_convert("re"))
o = Object.new
assert_nil(Regexp.try_convert(o))
def o.to_regexp() /foo/ end
assert_equal(/foo/, Regexp.try_convert(o))
end
# https://github.com/jruby/jruby/blob/master/spec/ruby/core/regexp/try_convert_spec.rb#L5
def test_jruby_returns_argument_if_given_regexp
assert_equal /foo/s, Regexp.try_convert(/foo/s)
end
# https://github.com/jruby/jruby/blob/master/spec/ruby/core/regexp/try_convert_spec.rb#L9
def test_jruby_returns_nil_if_given_arg_cant_be_converted
['', 'glark', [], Object.new, :pat].each do |arg|
assert_equal nil, Regexp.try_convert(arg)
end
end
# https://github.com/jruby/jruby/blob/master/test/externals/ruby1.9/uri/test_common.rb#L32
def test_jruby_uri_common_regexp
assert_instance_of Regexp, URI.regexp
assert_instance_of Regexp, URI.regexp(['http'])
assert_equal URI.regexp, URI.regexp
assert_equal 'http://', 'x http:// x'.slice(URI.regexp)
assert_equal 'http://', 'x http:// x'.slice(URI.regexp(['http']))
assert_equal 'http://', 'x http:// x ftp://'.slice(URI.regexp(['http']))
assert_equal nil, 'http://'.slice(URI.regexp([]))
assert_equal nil, ''.slice(URI.regexp)
assert_equal nil, 'xxxx'.slice(URI.regexp)
assert_equal nil, ':'.slice(URI.regexp)
assert_equal 'From:', 'From:'.slice(URI.regexp)
end
# https://github.com/jruby/jruby/blob/master/spec/ruby/core/regexp/union_spec.rb#L14
def test_jruby_quotes_string_arguments
assert_equal /n|\./, Regexp.union("n", ".")
end
end
to-regexp-0.2.1/History.txt 0000644 0001750 0001750 00000000712 13571230550 014653 0 ustar pravi pravi == 0.1.1 / 2012-02-22
* Bug fixes
* Fix edge case with Regexp.union(*ESCAPE_HTML.keys) seen in the wild with rack-1.2.5/lib/rack/utils.rb
== 0.1.0 / yanked!
* Enhancements
* New :literal option. For example, 'foo'.to_regexp(:literal => true, :ignore_case => true)
* Allow setting :ignore_case, :multiline, :extended as options passed to #to_regexp.
== 0.0.3 / 2011-04-27
* first production ready version!
== 0.0.2 / yanked!
== 0.0.1 / yanked!
to-regexp-0.2.1/README.rdoc 0000644 0001750 0001750 00000002214 13571230550 014256 0 ustar pravi pravi =to_regexp
Basically a safe way to convert strings to regexps (with options).
str = "/finalis(é)/im"
old_way = eval(str) # not safe
new_way = str.to_regexp # provided by this gem
old_way == new_way # true
You can also treat strings as literal regexps. These two are equivalent:
'/foo/'.to_regexp #=> /foo/
'foo'.to_regexp(:literal => true) #=> /foo/
If you need case insensitivity and you're using :literal, pass options like :ignore_case. These two are equivalent:
'/foo/i'.to_regexp #=> /foo/i
'foo'.to_regexp(:literal => true, :ignore_case => true) #=> /foo/i
You can get the options passed to Regexp.new with #as_regexp:
'/foo/'.to_regexp == Regexp.new('/foo/'.as_regexp) # true
Finally, you can be more lazy using :detect:
'foo'.to_regexp(detect: true) #=> /foo/
'foo\b'.to_regexp(detect: true) #=> %r{foo\\b}
'/foo\b/'.to_regexp(detect: true) #=> %r{foo\b}
'foo\b/'.to_regexp(detect: true) #=> %r{foo\\b/}
Copyright 2012 Seamus Abshere