Class: String

Class | String
In: | lib/core/facets/blank.rb lib/core/facets/boolean.rb lib/core/facets/comparable/cmp.rb lib/core/facets/kernel/object_state.rb lib/core/facets/string/align.rb lib/core/facets/string/bracket.rb lib/core/facets/string/bytes.rb lib/core/facets/string/camelcase.rb lib/core/facets/string/capitalized.rb lib/core/facets/string/chars.rb lib/core/facets/string/chomp.rb lib/core/facets/string/cleave.rb lib/core/facets/string/compress_lines.rb lib/core/facets/string/divide.rb lib/core/facets/string/each_char.rb lib/core/facets/string/each_word.rb lib/core/facets/string/expand_tab.rb lib/core/facets/string/file.rb lib/core/facets/string/fold.rb lib/core/facets/string/indent.rb lib/core/facets/string/interpolate.rb lib/core/facets/string/line_wrap.rb lib/core/facets/string/lines.rb lib/core/facets/string/tab.rb lib/core/facets/string/margin.rb lib/core/facets/string/methodize.rb lib/core/facets/string/modulize.rb lib/core/facets/string/mscan.rb lib/core/facets/string/natcmp.rb lib/core/facets/string/nchar.rb lib/core/facets/string/op_sub.rb lib/core/facets/string/pathize.rb lib/core/facets/string/range.rb lib/core/facets/string/rewrite.rb lib/core/facets/string/shatter.rb lib/core/facets/string/snakecase.rb lib/core/facets/string/splice.rb lib/core/facets/string/start_with.rb lib/core/facets/string/tabto.rb lib/core/facets/string/titlecase.rb lib/core/facets/string/to_re.rb lib/core/facets/string/underscore.rb lib/core/facets/string/unfold.rb lib/core/facets/string/uppercase.rb lib/core/facets/string/variablize.rb lib/core/facets/string/word_wrap.rb lib/core/facets/string/words.rb lib/core/facets/string/xor.rb lib/more/facets/date.rb lib/more/facets/random.rb lib/more/facets/succ.rb lib/more/facets/tuple.rb
Parent: | Object

Conveniently turn a string into a tuple.

### Methods

- ^ align align_center align_left align_right blank? bracket bracket! bytes camelcase capitalized? chars cleave cmp compress_lines dequote divide downcase? each_char each_word end_with? expand_tab expand_tabs file fold indent index_all interpolate lchomp lchomp! line_wrap lines lower_camelcase lowercase margin methodize modulize mscan natcmp nchar object_state outdent pathize quote range range_all range_of_line rewrite shatter snakecase splice start_with? starts_with? succ tab tabto titlecase to_b to_date to_datetime to_re to_rx to_t unbracket unbracket! underscore unfold upcase? upper_camelcase uppercase variablize word_wrap word_wrap! words

### Included Modules

Random

### Constants

BRA2KET | = | { '['=>']', '('=>')', '{'=>'}', '<'=>'>' }

### External Aliases

[]= | -> | store
| Alias for []=.
ends_with? | -> | ends_with?
succ | -> | succ1

### Public Class methods

interpolate(&str)

Interpolate. Provides a means of extenally using Ruby string interpolation mechinism.

      try = "hello"
      str = "\#{try}!!!"
      String.interpolate{ str }    #=> "hello!!!"

      NOTE: The block neccessary in order to get
            then binding of the caller.

CREDIT: Trans

[Source]

    # File lib/core/facets/string/interpolate.rb, line 15
      def self.interpolate(&str)
        eval "%{#{str.call}}", str.binding
      end

### Public Instance methods

-(pattern)

Removes occurances of a string or regexp.

      "HELLO HELLO" - "LL"    #=> "HEO HEO"

CREDIT: Benjamin David Oakes

[Source]

    # File lib/core/facets/string/op_sub.rb, line 9
      def -(pattern)
        self.gsub(pattern, '')
      end

^(aString)

Binary XOR of two strings.

      puts "\000\000\001\001" ^ "\000\001\000\001"
      puts  "\003\003\003" ^ "\000\001\002"

produces

      "\000\001\001\000"
      "\003\002\001"

[Source]

    # File lib/core/facets/string/xor.rb, line 13
      def ^(aString)
        a = self.unpack('C'*(self.length))
        b = aString.unpack('C'*(aString.length))
        if (b.length < a.length)
          (a.length - b.length).times { b << 0 }
        end
        xor = ""
        0.upto(a.length-1) { |pos|
          x = a[pos] ^ b[pos]
          xor << x.chr()
        }
        return(xor)
      end

align(direction, n, sep="\n", c=' ')

[Source]

    # File lib/core/facets/string/align.rb, line 3
      def align(direction, n, sep="\n", c=' ')
        case direction
        when :right
          align_right(n, sep="\n", c=' ')
        when :left
          align_left(n, sep="\n", c=' ')
        when :center
          align_center(n, sep="\n", c=' ')
        else
          raise ArgumentError
        end
      end

align_center(n, sep="\n", c=' ')

Centers each line of a string.

The default alignment separation is a new line ("\n"). This can be changed as can be the padding string which defaults to a single space (’ ’).

      s = <<-EOS
        This is a test
        and
        so on
      EOS

      puts s.align_center(14)

produces

      This is a test
           and
          so on

CREDIT: Trans

[Source]

    # File lib/core/facets/string/align.rb, line 98
      def align_center(n, sep="\n", c=' ')
        return center(n.to_i,c.to_s) if sep==nil
        q = split(sep.to_s).collect { |line|
          line.center(n.to_i,c.to_s)
        }
        q.join(sep.to_s)
      end

align_left(n, sep="\n", c=' ')

Align a string to the left.

The default alignment separation is a new line ("\n"). This can be changed as can be the padding string which defaults to a single space (’ ’).

      s = <<-EOS
      This is a test
        and
        so on
      EOS

      puts s.align_left(20, "\n", '.')

produces

      This is a test......
      and.................
      so on...............

CREDIT: Trans

[Source]

    # File lib/core/facets/string/align.rb, line 68
      def align_left(n, sep="\n", c=' ')
        return ljust(n.to_i,c.to_s) if sep==nil
        q = split(sep.to_s).map do |line|
          line.strip.ljust(n.to_i,c.to_s)
        end
        q.join(sep.to_s)
      end

align_right(n, sep="\n", c=' ')

Align a string to the right.

The default alignment separation is a new line ("\n"). This can be changed as can be the padding string which defaults to a single space (’ ’).

      s = <<-EOS
      This is a test
        and
        so on
      EOS

      puts s.align_right(14)

produces

      This is a test
                 and
               so on

CREDIT: Trans

[Source]

    # File lib/core/facets/string/align.rb, line 38
      def align_right(n, sep="\n", c=' ')
        return rjust(n.to_i,c.to_s) if sep==nil
        q = split(sep.to_s).map do |line|
          line.rjust(n.to_i,c.to_s)
        end
        q.join(sep.to_s)
      end

blank?()

Is this string just whitespace?

      "abc".blank?  #=> false
      "   ".blank?  #=> true

[Source]

    # File lib/core/facets/blank.rb, line 50
      def blank?
        self !~ /\S/
      end

bracket(bra, ket=nil)

Return a new string embraced by given brakets. If only one bracket char is given it will be placed on either side.

      "wrap me".bracket('{')        #=> "{wrap me}"
      "wrap me".bracket('--','!')   #=> "--wrap me!"

CREDIT: Trans

[Source]

    # File lib/core/facets/string/bracket.rb, line 14
      def bracket(bra, ket=nil)
        #ket = String.bra2ket[$&] if ! ket && /^[\[({<]$/ =~ bra
        ket = BRA2KET[bra] unless ket
        "#{bra}#{self}#{ket ? ket : bra}"
      end

bracket!(bra, ket=nil)

Inplace version of braket.

CREDIT: Trans

[Source]

    # File lib/core/facets/string/bracket.rb, line 24
      def bracket!(bra, ket=nil)
        self.replace(bracket(bra, ket))
      end

bytes(&blk)

Upacks string into bytes.

Note, this is not 100% compatible with 1.8.7+ which returns an enumerator instead of an array.

[Source]

    # File lib/core/facets/string/bytes.rb, line 10
        def bytes(&blk)
          if block_given?
            self.unpack('C*').each(&blk)
          else
            self.unpack('C*')
          end
        end

camelcase(first_letter=nil)

Converts a string to camelcase.

By default camelcase leaves the first character of the string as given. If `first_letter` is set to +:lower+ or `false`, then +camelcase+ will produce lowerCamelCase. If it is set to +:upper+ or `true` it will produce UpperCamelCase.

+camelcase+ also converts ’/’ to ’::’ which is useful for converting paths to namespaces.

Examples

      "camel_case".camelcase             #=> "camelCase"
      "camel/case".camelcase(true)       #=> "Camel::Case"
      "Camel_case".camelcase(false)      #=> "camelCase"

TODO: Is this the best approach? Should lowerCamelCase be default instead?

[Source]

    # File lib/core/facets/string/camelcase.rb, line 19
      def camelcase(first_letter=nil)
        case first_letter
        when :upper, true
          upper_camelcase
        when :lower, false
          lower_camelcase
        else
          str = dup
          str.gsub!(/\/(.?)/){ "::#{$1.upcase}" }  # NOT SO SURE ABOUT THIS
          str.gsub!(/(?:_+|-+)([a-z])/){ $1.upcase }
          #str.gsub!(/(\A|\s)([a-z])/){ $1 + $2.upcase }
          str
        end
      end

capitalized?()

Return true if the string is capitalized, otherwise false.

      "THIS".capitalized?  #=> true
      "This".capitalized?  #=> true
      "this".capitalized?  #=> false

CREDIT: Phil Tomson

[Source]

    # File lib/core/facets/string/capitalized.rb, line 11
      def capitalized?
        self =~ /^[A-Z]/
      end

chars()

Returns an array of characters.

      "abc".chars  #=> ["a","b","c"]

[Source]

    # File lib/core/facets/string/chars.rb, line 13
        def chars
          split(//)
        end

cleave(threshold=nil, len=nil)

Cleave a string. Break a string in two parts at the nearest whitespace.

CREDIT: Trans

[Source]

    # File lib/core/facets/string/cleave.rb, line 8
      def cleave(threshold=nil, len=nil)
        l = (len || size / 2)
        t = threshold || size

        h1 = self[0...l]
        h2 = self[l..-1]

        i1 = h1.rindex(/\s/) || 0
        d1 = (i1 - l).abs

        d2 = h2.index(/\s/) || l
        i2 = d2 + l

        d1 = (i1-l).abs
        d2 = (i2-l).abs

        if [d1, d2].min > t
          i = t
        elsif d1 < d2
          i = i1
        else
          i = i2
        end

        #dup.insert(l, "\n").gsub(/^\s+|\s+$/, '')
        return self[0..i].to_s.strip, self[i+1..-1].to_s.strip
      end

cmp(other)

Compare method that takes length into account. Unlike #<=>, this is compatible with succ.

      "abc".cmp("abc")   #=>  0
      "abcd".cmp("abc")  #=>  1
      "abc".cmp("abcd")  #=> -1
      "xyz".cmp("abc")   #=>  1

CREDIT: Peter Vanbroekhoven

[Source]

    # File lib/core/facets/comparable/cmp.rb, line 31
      def cmp(other)
        return -1 if length < other.length
        return 1 if length > other.length
        self <=> other  # alphabetic compare
      end

compress_lines(spaced = true)

Matches any whitespace (including newline) and replaces with a single space

@example

      <<-QUERY.compress_lines
        SELECT name
        FROM users
      QUERY
      => "SELECT name FROM users"

[Source]

    # File lib/core/facets/string/compress_lines.rb, line 12
      def compress_lines(spaced = true)
        split($/).map { |line| line.strip }.join(spaced ? ' ' : '')
      end

dequote()

Remove quotes from string.

      "'hi'".dequite    #=> "hi"

CREDIT: Trans

[Source]

    # File lib/core/facets/string/bracket.rb, line 88
      def dequote
        s = self.dup

        case self[0,1]
        when "'", '"', '`'
          s[0] = ''
        end

        case self[-1,1]
        when "'", '"', '`'
          s[-1] = ''
        end

        return s
      end

divide( re )

Breaks a string up into an array based on a regular expression. Similar to scan, but includes the matches.

      s = "<p>This<b>is</b>a test.</p>"
      s.divide( /\<.*?\>/ )

produces

      ["<p>This", "<b>is", "</b>a test.", "</p>"]

CREDIT: Trans

[Source]

    # File lib/core/facets/string/divide.rb, line 15
      def divide( re )
        re2 = /#{re}.*?(?=#{re}|\Z)/
        scan(re2) #{re}(?=#{re})/)
      end

downcase?()

Return true if the string is lowercase (downcase), otherwise false.

      "THIS".downcase?  #=> false
      "This".downcase?  #=> false
      "this".downcase?  #=> true

CREDIT: Phil Tomson

[Source]

    # File lib/core/facets/string/capitalized.rb, line 23
      def downcase?
        downcase == self
      end

each_char() {|scanner.scan(char || break)| ...}

Yields a single-character string for each character in the string. When $KCODE = ‘UTF8’, multi-byte characters are yielded appropriately.

[Source]

    # File lib/core/facets/string/each_char.rb, line 22
        def each_char
          scanner, char = StringScanner.new(self), /./mu
          loop { yield(scanner.scan(char) || break) }
        end

each_word(&block)

Iterate through each word of a string.

      "a string".each_word { |word| ... }

[Source]

    # File lib/core/facets/string/each_word.rb, line 9
      def each_word(&block)
        words.each(&block)
      end

end_with?(suffix)

Does a string end with the given suffix?

      "hello".ends_with?("lo")    #=> true
      "hello".ends_with?("to")    #=> false

CREDIT: Lucas Carlson, Blaine Cook

[Source]

    # File lib/core/facets/string/start_with.rb, line 27
        def end_with?(suffix)
          self.rindex(suffix) == size - suffix.size
        end

expand_tab(n=8)

Expands tabs to `n` spaces. Non-destructive. If `n` is 0, then tabs are simply removed. Raises an exception if `n` is negative.

      "\t\tHey".expand_tab(2)  #=> "    Hey"

Thanks to GGaramuno for a more efficient algorithm. Very nice.

CREDIT: Gavin Sinclair, Noah Gibbs, GGaramuno

[Source]

    # File lib/core/facets/string/expand_tab.rb, line 13
      def expand_tab(n=8)
        n = n.to_int
        raise ArgumentError, "n must be >= 0" if n < 0
        return gsub(/\t/, "") if n == 0
        return gsub(/\t/, " ") if n == 1
        str = self.dup
        while
          str.gsub!(/^([^\t\n]*)(\t+)/) { |f|
            val = ( n * $2.size - ($1.size % n) )
            $1 << (' ' * val)
          }
        end
        str
      end

expand_tabs(n=8)

Alias for expand_tab

file()

Use fluent notation for making file directives.

       '~/trans/Desktop/notes.txt'.file.mtime

[Source]

    # File lib/core/facets/string/file.rb, line 9
      def file
        f = self
        Functor.new do |op, *a|
          File.send(op, f, *a)
        end
      end

fold(ignore_indented=false)

Returns a new string with all new lines removed from adjacent lines of text.

      s = "This is\na test.\n\nIt clumps\nlines of text."
      s.fold

produces

      "This is a test.\n\nIt clumps lines of text. "

One arguable flaw with this, that might need a fix: if the given string ends in a newline, it is replaced with a single space.

CREDIT: Trans

[Source]

    # File lib/core/facets/string/fold.rb, line 19
      def fold(ignore_indented=false)
        ns = ''
        i = 0
        br = self.scan(/(\n\s*\n|\Z)/m) do |m|
          b = $~.begin(1)
          e = $~.end(1)
          nl = $&
          tx = slice(i...b)
          if ignore_indented and slice(i...b) =~ /^[ ]+/
            ns << tx
          else
            ns << tx.gsub(/[ ]*\n+/,' ')
          end
          ns << nl
          i = e
        end
        ns
      end

indent(n)

Indent left or right by n spaces. (This used to be called tab and aliased as indent.)

CREDIT: Gavin Sinclair, Trans

[Source]

    # File lib/core/facets/string/indent.rb, line 8
      def indent(n)
        if n >= 0
          gsub(/^/, ' ' * n)
        else
          gsub(/^ {0,#{-n}}/, "")
        end
      end

index_all(s, reuse=false)

Like index but returns an array of all index locations. The reuse flag allows the trailing portion of a match to be reused for subsquent matches.

      "abcabcabc".index_all('a')  #=> [0,3,6]

      "bbb".index_all('bb', false)  #=> [0]
      "bbb".index_all('bb', true)   #=> [0,1]

TODO: Culd probably be defined for Indexable in general too.

[Source]

    # File lib/core/facets/string/range.rb, line 66
      def index_all(s, reuse=false)
        s = Regexp.new(Regexp.escape(s)) unless Regexp===s
        ia = []; i = 0
        while (i = index(s,i))
          ia << i
          i += (reuse ? 1 : $~[0].size)
        end
        ia
      end

lchomp(match)

Left chomp.

      "help".lchomp("h")  #=> "elp"
      "help".lchomp("k")  #=> "help"

CREDIT: Trans

[Source]

    # File lib/core/facets/string/chomp.rb, line 10
      def lchomp(match)
        if index(match) == 0
          self[match.size..-1]
        else
          self.dup
        end
      end

lchomp!(match)

In-place left chomp.

      "help".lchomp("h")  #=> "elp"
      "help".lchomp("k")  #=> "help"

CREDIT: Trans

[Source]

    # File lib/core/facets/string/chomp.rb, line 25
      def lchomp!(match)
        if index(match) == 0
          self[0...match.size] = ''
          self
        end
      end

line_wrap(width, tabs=4)

Line wrap at width.

      puts "1234567890".line_wrap(5)

produces

      12345
      67890

CREDIT: Trans

[Source]

    # File lib/core/facets/string/line_wrap.rb, line 14
      def line_wrap(width, tabs=4)
        s = gsub(/\t/,' ' * tabs) # tabs default to 4 spaces
        s = s.gsub(/\n/,' ')
        r = s.scan( /.{1,#{width}}/ )
        r.join("\n") << "\n"
      end

lines(&blk)

Returns an array of characters.

      "abc\n123".lines  #=> ["abc","123"]

Note, this is not 100% compatible with 1.8.7+ which returns an enumerator instead of an array.

[Source]

    # File lib/core/facets/string/lines.rb, line 12
        def lines(&blk)
          if block_given?
            self.split(/\n/).each(&blk)
          else
            self.split(/\n/)
          end
        end

lower_camelcase()

[Source]

    # File lib/core/facets/string/camelcase.rb, line 42
      def lower_camelcase
        str = dup
        str.gsub!(/\/(.?)/){ "::#{$1.upcase}" }  # NOT SO SURE ABOUT THIS
        str.gsub!(/(?:_+|-+)([a-z])/){ $1.upcase }
        str.gsub!(/(\A|\s)([A-Z])/){ $1 + $2.downcase }
        str
      end

lowercase()

Downcase first letter.

[Source]

    # File lib/core/facets/string/uppercase.rb, line 17
      def lowercase
        str = to_s
        str[0,1].downcase + str[1..-1]
      end

margin(n=0)

Provides a margin controlled string.

      x = %Q{
            | This
            |   is
            |     margin controlled!
            }.margin

NOTE: This may still need a bit of tweaking.

CREDIT: Trans

[Source]

    # File lib/core/facets/string/margin.rb, line 16
      def margin(n=0)
        #d = /\A.*\n\s*(.)/.match( self )[1]
        #d = /\A\s*(.)/.match( self)[1] unless d
        d = ((/\A.*\n\s*(.)/.match(self)) ||
            (/\A\s*(.)/.match(self)))[1]
        return '' unless d
        if n == 0
          gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, '')
        else
          gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, ' ' * n)
        end
      end

methodize()

Translate a (class or module) name to a suitable method name.

      My::CoolClass.name.methodize => "my__cool_class"

[Source]

    # File lib/core/facets/string/methodize.rb, line 17
      def methodize
        gsub(/([A-Z]+)([A-Z])/,'\1_\2').
        gsub(/([a-z])([A-Z])/,'\1_\2').
        gsub('/' ,'__').
        gsub('::','__').
        downcase
      end

modulize()

Converts a string to module name representation.

This is essentially camelcase. It also converts ’/’ to ’::’ which is useful for converting paths to namespaces.

Examples

      "method_name".modulize    #=> "MethodName"
      "method/name".modulize    #=> "Method::Name"

[Source]

    # File lib/core/facets/string/modulize.rb, line 21
      def modulize
        gsub('__','/').
        gsub(/\/(.?)/){ "::#{$1.upcase}" }.
        gsub(/(?:_+|-+)([a-z])/){ $1.upcase }.
        gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase }
      end

mscan(re) {|| ...}

Like scan but returns MatchData ($~) rather then matched string ($&).

CREDIT: Trans

[Source]

    # File lib/core/facets/string/mscan.rb, line 8
      def mscan(re) #:yield:
        if block_given?
          scan(re) { yield($~) }
        else
          m = []
          scan(re) { m << $~ }
          m
        end
      end

natcmp(str2, caseInsensitive=false)

‘Natural order’ comparison of strings, e.g.

      "my_prog_v1.1.0" < "my_prog_v1.2.0" < "my_prog_v1.10.0"

which does not follow alphabetically. A secondary parameter, if set to true, makes the comparison case insensitive.

      "Hello.10".natcmp("Hello.1")  #=> -1

      TODO: Invert case flag?

CREDIT: Alan Davies, Martin Pool

[Source]

    # File lib/core/facets/string/natcmp.rb, line 46
      def natcmp(str2, caseInsensitive=false)
        str1 = self.dup
        str2 = str2.dup
        compareExpression = /^(\D*)(\d*)(.*)$/

        if caseInsensitive
          str1.downcase!
          str2.downcase!
        end

        # remove all whitespace
        str1.gsub!(/\s*/, '')
        str2.gsub!(/\s*/, '')

        while (str1.length > 0) or (str2.length > 0) do
          # Extract non-digits, digits and rest of string
          str1 =~ compareExpression
          chars1, num1, str1 = $1.dup, $2.dup, $3.dup
          str2 =~ compareExpression
          chars2, num2, str2 = $1.dup, $2.dup, $3.dup
          # Compare the non-digits
          case (chars1 <=> chars2)
            when 0 # Non-digits are the same, compare the digits...
              # If either number begins with a zero, then compare alphabetically,
              # otherwise compare numerically
              if (num1[0] != 48) and (num2[0] != 48)
                num1, num2 = num1.to_i, num2.to_i
              end
              case (num1 <=> num2)
                when -1 then return -1
                when 1 then return 1
              end
            when -1 then return -1
            when 1 then return 1
          end # case
        end # while

        # strings are naturally equal.
        return 0
      end

    end

nchar(n, replacement=nil)

Returns n characters of the string. If n is positive the characters are from the beginning of the string. If n is negative from the end of the string.

Alternatively a replacement string can be given, which will replace the n characters.

       str = "this is text"
       str.nchar(4)            #=> "this"
       str.nchar(4, 'that')    #=> "that"
       str                     #=> "that is text"

[Source]

    # File lib/core/facets/string/nchar.rb, line 15
      def nchar(n, replacement=nil)
        if replacement
          s = self.dup
          n > 0 ? (s[0...n] = replacement) : (s[n..-1] = replacement)
          return s
        else
          n > 0 ? self[0...n] : self[n..-1]
        end
      end

object_state(data=nil)

[Source]

    # File lib/core/facets/kernel/object_state.rb, line 35
      def object_state(data=nil)
        data ? replace(data) : dup
      end

outdent(n)

Outdent just indents a negative number of spaces.

CREDIT: Noah Gibbs

[Source]

    # File lib/core/facets/string/indent.rb, line 20
      def outdent(n)
        indent(-n)
      end

pathize()

Converts a (class or module) name to a unix path.

      My::CoolClass.name.pathize  #=> "my/cool_class"

[Source]

    # File lib/core/facets/string/pathize.rb, line 17
      def pathize
        gsub(/([A-Z]+)([A-Z])/,'\1_\2').
        gsub(/([a-z])([A-Z])/,'\1_\2').
        gsub('__','/').
        gsub('::','/').
        downcase
      end

quote(type=:s)

Return a new string embraced by given quotes. If no quotes are specified, then assumes single quotes.

      "quote me".quote     #=> "'quote me'"
      "quote me".quote(2)  #=> "\"quote me\""

CREDIT: Trans

[Source]

    # File lib/core/facets/string/bracket.rb, line 69
      def quote(type=:s)
        case type.to_s.downcase
        when 's', 'single'
          bracket("'")
        when 'd', 'double'
          bracket('"')
        when 'b', 'back'
          bracket('`')
        else
          bracket("'")
        end
      end

range(s, offset=0)

Like index but returns a Range.

      "This is a test!".range('test')  #=> 10..13

CREDIT: Trans

[Source]

    # File lib/core/facets/string/range.rb, line 9
      def range(s, offset=0)
        if index(s, offset)
          return ($~.begin(0))..($~.end(0)-1)
        end
        nil
      end

range_all(s, reuse=false)

Like index_all but returns an array of Ranges.

      "abc123abc123".range_all('abc')  #=> [0..2, 6..8]

      TODO: Add offset, perhaps ?

CREDIT: Trans

[Source]

    # File lib/core/facets/string/range.rb, line 24
      def range_all(s, reuse=false)
        r = []; i = 0
        while i < self.length
          rng = range(s, i)
          if rng
            r << rng
            i += reuse ? 1 : rng.end + 1
          else
            break
          end
        end
        r.uniq
      end

range_of_line()

Returns an array of ranges mapping the characters per line.

      "this\nis\na\ntest".range_of_line
      #=> [0..4, 5..7, 8..9, 10..13]

CREDIT: Trans

[Source]

    # File lib/core/facets/string/range.rb, line 46
      def range_of_line
        offset=0; charmap = []
        self.each do |line|
          charmap << (offset..(offset + line.length - 1))
          offset += line.length
        end
        charmap
      end

rewrite(rules)

Apply a set of rules (regular expression matches) to the string.

### Requirements:

The rules must be applied in order! So we cannot use a hash because the ordering is not guaranteed! we use an array instead.

### Input:

The array containing rule-pairs (match, write).

### Output:

The rewritten string.

CREDIT: George Moschovitis

[Source]

    # File lib/core/facets/string/rewrite.rb, line 18
      def rewrite(rules)
        raise ArgumentError.new('The rules parameter is nil') unless rules
        rewritten_string = dup
        rules.each do |match,write|
          rewritten_string.gsub!(match,write)
        end
        return rewritten_string
      end

shatter( re )

Breaks a string up into an array based on a regular expression. Similar to scan, but includes the matches.

      s = "<p>This<b>is</b>a test.</p>"
      s.shatter( /\<.*?\>/ )

produces

      ["<p>", "This", "<b>", "is", "</b>", "a test.", "</p>"]

CREDIT: Trans

[Source]

    # File lib/core/facets/string/shatter.rb, line 15
      def shatter( re )
        r = self.gsub( re ){ |s| "\1" + s + "\1" }
        while r[0,1] == "\1" ; r[0] = '' ; end
        while r[-1,1] == "\1" ; r[-1] = '' ; end
        r.split("\1")
      end

snakecase()

The reverse of `camelcase`. Makes an underscored of a camelcase string.

Changes ’::’ to ’/’ to convert namespaces to paths.

Examples

      "SnakeCase".snakecase           #=> "snake_case"
      "Snake-Case".snakecase          #=> "snake_case"
      "SnakeCase::Errors".snakecase   #=> "snake_case/errors"

[Source]

    # File lib/core/facets/string/snakecase.rb, line 12
      def snakecase
        gsub(/::/, '/').  # NOT SO SURE ABOUT THIS
        gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
        gsub(/([a-z\d])([A-Z])/,'\1_\2').
        tr("-", "_").
        downcase
      end

splice(idx, sub=nil)

This is basically the same as store, but it acts like slice! when given only one argument.

Essentlay slice, but writes rather than reads.

      a = "HELLO"
      a.splice("X", 1)
      a                #=> "HXLLO"

      a = "HELLO"
      a.splice(1)    #=> "E"
      a              #=> "HLLO"

CREDIT: Trans

[Source]

    # File lib/core/facets/string/splice.rb, line 20
      def splice(idx, sub=nil)
        if sub
          store(idx, sub)
        else
          case idx
          when Range
            slice!(idx)
          else
            slice!(idx,1)
          end
        end
      end

start_with?(prefix)

Does a string start with the given prefix.

      "hello".starts_with?("he")    #=> true
      "hello".starts_with?("to")    #=> false

CREDIT: Lucas Carlson, Blaine Cook

[Source]

    # File lib/core/facets/string/start_with.rb, line 12
        def start_with?(prefix)
          self.index(prefix) == 0
        end

starts_with?(prefix)

Alias for start_with?

succ(n=1)

Allows succ to take n step increments.

      "abc".succ      #=> "abd"
      "abc".succ(4)   #=> "abg"
      "abc".succ(24)  #=> "aca"

CREDIT: Trans

[Source]

    # File lib/more/facets/succ.rb, line 37
      def succ(n=1)
        s = self
        n.times { s = s.succ1 }
        s
      end

tab(n)

Aligns each line n spaces.

CREDIT: Gavin Sinclair

[Source]

    # File lib/core/facets/string/tab.rb, line 12
      def tab(n)
        gsub(/^ */, ' ' * n)
      end

tabto(n)

Preserves relative tabbing. The first non-empty line ends up with n spaces before nonspace.

CREDIT: Gavin Sinclair

[Source]

    # File lib/core/facets/string/tabto.rb, line 10
      def tabto(n)
        if self =~ /^( *)\S/
          indent(n - $1.length)
        else
          self
        end
      end

titlecase()

Title case.

      "this is a string".titlecase
      => "This Is A String"

CREDIT: Eliazar Parra

[Source]

    # File lib/core/facets/string/titlecase.rb, line 10
      def titlecase
        gsub(/\b\w/){$&.upcase}
      end

to_b()

Interpret common affirmative string meanings as true, otherwise false. Balnk sapce and case are ignored. The following strings that will return true:

      <tt>true</tt>,<tt>yes</tt>,<tt>on</tt>,<tt>t</tt>,<tt>1</tt>,<tt>y</tt>,<tt>==</tt>

Examples:

      "true".to_b   #=> true
      "yes".to_b    #=> true
      "no".to_b     #=> false
      "123".to_b    #=> false

[Source]

    # File lib/core/facets/boolean.rb, line 43
      def to_b
        case self.downcase.strip
        when 'true', 'yes', 'on', 't', '1', 'y', '=='
          return true
        when 'nil', 'null'
          return nil
        else
          return false
        end
      end

to_date()

Parse data from string.

[Source]

    # File lib/more/facets/date.rb, line 390
      def to_date
        #::Date::civil(*ParseDate.parsedate(self)[0..2])
        ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
      end

to_datetime()

Convert string to DateTime.

[Source]

    # File lib/more/facets/date.rb, line 384
      def to_datetime
        date = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec).map { |arg| arg || 0 }
        ::DateTime.civil(*date)
      end

to_re(esc=false)

Turns a string into a regular expression.

      "a?".to_re  #=> /a?/

CREDIT: Trans

[Source]

    # File lib/core/facets/string/to_re.rb, line 9
      def to_re(esc=false)
        Regexp.new((esc ? Regexp.escape(self) : self))
      end

to_rx(esc=true)

Turns a string into a regular expression. By default it will escape all characters. Use `false` argument to turn off escaping.

      "[".to_rx  #=> /\[/

CREDIT: Trans

[Source]

    # File lib/core/facets/string/to_re.rb, line 21
      def to_rx(esc=true)
        Regexp.new((esc ? Regexp.escape(self) : self))
      end

to_t( &yld )

Translates a string in the form on a set of numerical and/or alphanumerical characters separated by non-word characters (eg \W+) into a Tuple. The values of the tuple will be converted to integers if they are purely numerical.

      '1.2.3a'.to_t  #=> [1,2,"3a"]

It you would like to control the interpretation of each value as it is added to the tuple you can supply a block.

      '1.2.3a'.to_t { |v| v.upcase }  #=> ["1","2","3A"]

This method calls Tuple.cast_from_string.

[Source]

    # File lib/more/facets/tuple.rb, line 309
      def to_t( &yld )
        Tuple.cast_from_string( self, &yld )
      end

unbracket(bra=nil, ket=nil)

Return a new string embraced by given brakets. If only one bracket char is given it will be placed on either side.

      "{unwrap me}".debracket('{')        #=> "unwrap me"
      "--unwrap me!".debracket('--','!')  #=> "unwrap me!"

CREDIT: Trans

[Source]

    # File lib/core/facets/string/bracket.rb, line 37
      def unbracket(bra=nil, ket=nil)
        if bra
          ket = BRA2KET[bra] unless ket
          ket = ket ? ket : bra
          s = self.dup
          s.gsub!(%r[^#{Regexp.escape(bra)}], '')
          s.gsub!(%r[#{Regexp.escape(ket)}$], '')
          return s
        else
          if m = BRA2KET[ self[0,1] ]
            return self.slice(1...-1) if self[-1,1]  == m
          end
        end
        return self.dup  # if nothing else
      end

unbracket!(bra=nil, ket=nil)

Inplace version of debraket.

CREDIT: Trans

[Source]

    # File lib/core/facets/string/bracket.rb, line 57
      def unbracket!(bra=nil, ket=nil)
        self.replace( unbracket(bra, ket) )
      end

underscore()

The reverse of `camelcase`. Makes an underscored of a camelcase string.

Changes ’::’ to ’/’ to convert namespaces to paths.

Examples

      "SnakeCase".underscore           #=> "snake_case"
      "Snake-Case".underscore          #=> "snake_case"
      "SnakeCase::Errors".underscore   #=> "snake_case/errors"

[Source]

    # File lib/core/facets/string/underscore.rb, line 12
      def underscore
        gsub(/::/, '/').
        gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
        gsub(/([a-z\d])([A-Z])/,'\1_\2').
        tr("-", "_").
        downcase
      end

unfold()

Unfold paragrpahs.

FIXME: Sometimes adds one too many blank lines. TEST!!!

[Source]

    # File lib/core/facets/string/unfold.rb, line 7
      def unfold
        blank = false
        text  = ''
        split(/\n/).each do |line|
          if /\S/ !~ line
            text << "\n\n"
            blank = true
          else
            if /^(\s+|[*])/ =~ line
              text << (line.rstrip + "\n")
            else
              text << (line.rstrip + " ")
            end
            blank = false
          end
        end
        text = text.gsub(/(\n){3,}/,"\n\n")
        text.rstrip
      end

upcase?()

Is the string upcase/uppercase?

      "THIS".upcase?  #=> true
      "This".upcase?  #=> false
      "this".upcase?  #=> false

CREDIT: Phil Tomson

[Source]

    # File lib/core/facets/string/capitalized.rb, line 38
      def upcase?
        upcase == self
      end

upper_camelcase()

[Source]

    # File lib/core/facets/string/camelcase.rb, line 34
      def upper_camelcase
        str = dup
        str.gsub!(/\/(.?)/){ "::#{$1.upcase}" }  # NOT SO SURE ABOUT THIS
        str.gsub!(/(?:_+|-+)([a-z])/){ $1.upcase }
        str.gsub!(/(\A|\s)([a-z])/){ $1 + $2.upcase }
        str
      end

uppercase()

Upcase first letter.

NOTE: One might argue that this method should behave the same as +upcase+ and rather this behavior should be in place of +captialize+. Probably so, but since Matz has already defined +captialize+ the way it is, this name seems most fitting to the missing behavior.

[Source]

    # File lib/core/facets/string/uppercase.rb, line 10
      def uppercase
        str = to_s
        str[0,1].upcase + str[1..-1]
      end

variablize()

Prepend an "@" to the beginning of a string to make a instance variable name. This also replaces non-valid characters with underscores.

[Source]

    # File lib/core/facets/string/variablize.rb, line 7
      def variablize
        v = gsub(/\W/, '_')
        "@#{v}"
      end

word_wrap( col_width=80 )

Word wrap a string not exceeding max width.

      puts "this is a test".word_wrap(4)

produces

      this
      is a
      test

This is basic implementation of word wrap, but smart enough to suffice for most use cases.

CREDIT: Gavin Kistner, Dayne Broderson

[Source]

    # File lib/core/facets/string/word_wrap.rb, line 18
      def word_wrap( col_width=80 )
        self.dup.word_wrap!( col_width )
      end

word_wrap!( col_width=80 )

As with word_wrap, but modifies the string in place.

CREDIT: Gavin Kistner, Dayne Broderson

[Source]

    # File lib/core/facets/string/word_wrap.rb, line 26
      def word_wrap!( col_width=80 )
        self.gsub!( /(\S{#{col_width}})(?=\S)/, '\1 ' )
        self.gsub!( /(.{1,#{col_width}})(?:\s+|$)/, "\\1\n" )
        self
      end

words()

Returns an array of characters.

      "abc 123".words  #=> ["abc","123"]

[Source]

    # File lib/core/facets/string/words.rb, line 7
      def words
        self.split(/\s+/)
      end

[Validate]