to-regexp-0.2.1/0000755000175000017500000000000013571230550012451 5ustar pravipravito-regexp-0.2.1/LICENSE0000644000175000017500000000205713571230550013462 0ustar pravipraviCopyright (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/CHANGELOG0000644000175000017500000000063213571230550013664 0ustar pravipravi0.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/Rakefile0000644000175000017500000000051113571230550014113 0ustar pravipravirequire '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/Gemfile0000644000175000017500000000012113571230550013736 0ustar pravipravisource :rubygems # Specify your gem's dependencies in to_regexp.gemspec gemspec to-regexp-0.2.1/.gitignore0000644000175000017500000000005713571230550014443 0ustar pravipravi*.gem .bundle Gemfile.lock pkg/* doc/ .yardoc/ to-regexp-0.2.1/to_regexp.gemspec0000644000175000017500000000160013571230550016007 0ustar pravipravi# -*- 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/0000755000175000017500000000000013571230550013217 5ustar pravipravito-regexp-0.2.1/lib/to_regexp.rb0000644000175000017500000000552013571230550015542 0ustar pravipravi# 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/0000755000175000017500000000000013571230550015213 5ustar pravipravito-regexp-0.2.1/lib/to_regexp/version.rb0000644000175000017500000000005013571230550017220 0ustar pravipravimodule ToRegexp VERSION = '0.2.1' end to-regexp-0.2.1/test/0000755000175000017500000000000013571230550013430 5ustar pravipravito-regexp-0.2.1/test/helper.rb0000644000175000017500000000041313571230550015232 0ustar pravipraviunless 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.rb0000644000175000017500000001531013571230550017010 0ustar pravipravi# 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.txt0000644000175000017500000000071213571230550014653 0ustar pravipravi== 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.rdoc0000644000175000017500000000221413571230550014256 0ustar pravipravi=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