- align_center
- align_left
- align_right
- at_rand
- at_rand!
- basename
- blank?
- bra2ket
- bracket
- bracket!
- brief
- bytes
- camelcase
- camelize
- capitalized?
- chars
- cmp
- dequote
- downcase?
- dresner
- dresner!
- each_char
- each_word
- ends_with?
- entropy
- first
- first!
- first=
- first_char
- fold
- format
- format
- frequency
- fuzzy_match
- humanize
- indent
- index_all
- interpolate
- last
- last!
- last=
- last_char
- line_wrap
- lines
- lowercase?
- margin
- methodize
- modulize
- mscan
- natcmp
- nchar
- ordinal
- pathize
- patterns
- plural
- pluralize
- pop
- pot
- probability
- pull
- push
- quote
- rand_byte
- rand_byte!
- rand_index
- rand_letter
- random
- range
- range_all
- range_of_line
- regesc
- shatter
- shell_escape
- shift
- shuffle
- shuffle!
- similarity
- singular
- singularize
- soundex
- soundex_code
- sprintf
- starts_with?
- succ
- tab
- tabto
- to_a
- to_b
- to_const
- to_date
- to_proc
- to_re
- to_rx
- to_time
- unbracket
- unbracket!
- underscore
- unix_crypt
- unix_crypt!
- unpack
- unshift
- upcase?
- uppercase?
- whitespace?
- whitespace?
- word_filter
- word_filter!
- word_wrap
- word_wrap!
- words
SINGULAR_RULES | = | [ [/(matr)ices$/i, '\1ix'], [/(vert)ices$/i, '\1ex'], [/^(ox)en/i, '\1'], [/(alias)es$/i, '\1'], [/([octop|vir])i$/i, '\1us'], [/(cris|ax|test)es$/i, '\1is'], [/(shoe)s$/i, '\1'], [/(o)es$/i, '\1'], [/(bus)es$/i, '\1'], [/([m|l])ice$/i, '\1ouse'], [/(x|ch|ss|sh)es$/i, '\1'], [/(m)ovies$/i, '\1\2ovie'], [/(s)eries$/i, '\1\2eries'], [/([^aeiouy]|qu)ies$/i, '\1y'], [/([lr])ves$/i, '\1f'], [/(tive)s$/i, '\1'], [/(hive)s$/i, '\1'], [/([^f])ves$/i, '\1fe'], [/(^analy)ses$/i, '\1sis'], [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis'], [/([ti])a$/i, '\1um'], [/(p)eople$/i, '\1\2erson'], [/(m)en$/i, '\1an'], [/(s)tatus$/i, '\1\2tatus'], [/(c)hildren$/i, '\1\2hild'], [/(n)ews$/i, '\1\2ews'], [/s$/i, ''] |
PLURAL_RULES | = | [ [/^(ox)$/i, '\1\2en'], # ox [/([m|l])ouse$/i, '\1ice'], # mouse, louse [/(matr|vert)ix|ex$/i, '\1ices'], # matrix, vertex, index [/(x|ch|ss|sh)$/i, '\1es'], # search, switch, fix, box, process, address [/([^aeiouy]|qu)ies$/i, '\1y'], [/([^aeiouy]|qu)y$/i, '\1ies'], # query, ability, agency [/(hive)$/i, '\1s'], # archive, hive [/(?:([^f])fe|([lr])f)$/i, '\1\2ves'], # half, safe, wife [/sis$/i, 'ses'], # basis, diagnosis [/([ti])um$/i, '\1a'], # datum, medium [/(p)erson$/i, '\1eople'], # person, salesperson [/(m)an$/i, '\1en'], # man, woman, spokesman [/(c)hild$/i, '\1hildren'], # child [/(buffal|tomat|potat)o$/i, '\1\2oes'], # buffalo, tomato [/(bu)s$/i, '\1\2ses'], # bus [/(alias)/i, '\1es'], # alias [/(octop|vir)us$/i, '\1i'], # octopus, virus - virus has no defined plural, but viri is better than viruses/viruss [/(ax|cri|test)is$/i, '\1es'], # axis, crisis [/s$/i, 's'], # no change (compatibility) [/$/, 's'] |
[ show source ]
# File lib/facets/core/string/bracket.rb, line 4 def self.bra2ket @bra2ket ||= { '['=>']', '('=>')', '{'=>'}', '<'=>'>' } end
[ show source ]
# File lib/facets/core/string/self/format.rb, line 2 def String.format(*args) Kernel.format(*args) end
[ show source ]
# File lib/facets/core/string/self/interpolate.rb, line 4 def self.interpolate(&str) eval "%{#{str.call}}", str.binding end
Returns a Regexp pattern based on the given pattern string or symbolic name.
Recognized names are:
- :char
- :word
- :line
They are also recognizied in plural form.
[ show source ]
# File lib/facets/core/string/self/patterns.rb, line 14 def self.patterns( pattern ) case pattern when :char, :chars, :character, :characters pattern = // when :word, :words pattern = /\s+|\Z/ when :line, :lines pattern = /\Z/ when String pattern = Regexp.new(Regexp.escape(pattern)) end pattern end
Module method to generate a random letter.
String::Random.rand_letter #=> "q" String::Random.rand_letter #=> "r" String::Random.rand_letter #=> "a"
[ show source ]
# File lib/facets/core/string/self/rand_letter.rb, line 9 def self.rand_letter (rand(26) + (rand(2) == 0 ? 65 : 97) ).chr end
Returns a randomly generated string. One possible use is password initialization. Takes a max legnth of characters (default 8) and an optional valid char Regexp (default /\w\d/).
[ show source ]
# File lib/facets/core/string/self/random.rb, line 14 def String.random(max_length = 8, char_re = /[\w\d]/) # gmosx: this is a nice example of input parameter checking. # this is NOT a real time called method so we can add this # check. Congrats to the author. raise ArgumentError.new('char_re must be a regular expression!') unless char_re.is_a?(Regexp) string = "" while string.length < max_length ch = rand(255).chr string << ch if ch =~ char_re end return string end
Support function for String#soundex. Returns code for a single character.
[ show source ]
# File lib/facets/core/string/soundex.rb, line 40 def String.soundex_code(character) character.tr! "AEIOUYWHBPFVCSKGJQXZDTLMNR", "00000000111122222222334556" end
[ show source ]
# File lib/facets/core/string/self/format.rb, line 6 def String.sprintf(*args) Kernel.format(*args) end
Centers each line of a string.
s = <<-EOS This is a test and so on EOS puts s.align_center(14)
produces
This is a test and so on
Align a string to the center. The defualt alignment seperation is a new line ("/n") This can be changed as can be the padding string which defaults to a single space (’ ’).
[ show source ]
# File lib/facets/core/string/align_center.rb, line 47 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 a string to the left. The defualt alignment seperation is a new line ("/n") This can be changes as can be the padding string which defaults to a single space (’ ’).
[ show source ]
# File lib/facets/core/string/align_center.rb, line 20 def align_left( n, sep="\n", c=' ' ) return ljust(n.to_i,c.to_s) if sep==nil q = split(sep.to_s).collect { |line| line.ljust(n.to_i,c.to_s) } q.join(sep.to_s) end
Align a string to the right. The defualt alignment seperation is a new line ("/n") This can be changes as can be the padding string which defaults to a single space (’ ’).
[ show source ]
# File lib/facets/core/string/align_center.rb, line 8 def align_right( n, sep="\n", c=' ' ) return rjust(n.to_i,c.to_s) if sep==nil q = split(sep.to_s).collect { |line| line.rjust(n.to_i,c.to_s) } q.join(sep.to_s) end
Return a random separation of the string. Default separation is by charaacter.
"Ruby rules".at_rand(' ') #=> ["Ruby"]
[ show source ]
# File lib/facets/core/string/at_rand.rb, line 13 def at_rand( separator=// ) separator = self.class.patterns( separator ) self.split(separator,-1).at_rand end
Return a random separation while removing it from the string. Default separation is by character.
s = "Ruby rules" s = at_rand!(' ') #=> "Ruby" s #=> "rules"
[ show source ]
# File lib/facets/core/string/at_rand.rb, line 25 def at_rand!( separator=// ) separator = self.class.patterns( separator ) a = self.shatter( separator ) w = []; a.each_with_index { |s,i| i % 2 == 0 ? w << s : w.last << s } i = rand( w.size ) r = w.delete_at( i ) self.replace( w.join('') ) return r end
Removes prepend module namespace.
"Test::Unit".basename #=> "Unit"
[ show source ]
# File lib/facets/core/string/basename.rb, line 8 def basename self.to_s.gsub(/^.*::/, '') end
Is this string just whitespace?
"abc".blank? #=> false " ".blank? #=> true
[ show source ]
# File lib/facets/core/string/blank.rb, line 9 def blank? self !~ /\S/ end
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!"
[ show source ]
# File lib/facets/core/string/bracket.rb, line 15 def bracket(bra, ket=nil) #ket = String.bra2ket[$&] if ! ket && /^[\[({<]$/ =~ bra ket = String.bra2ket[bra] unless ket "#{bra}#{self}#{ket ? ket : bra}" end
Inplace version of braket.
[ show source ]
# File lib/facets/core/string/bracket.rb, line 22 def bracket!(bra, ket=nil) self.replace( self.bracket(bra, ket) ) end
Returns short abstract of long strings (first ‘count’ characters, chopped at the nearest word, appended by ’…’) force_cutoff: break forcibly at ‘count’ chars. Does not accept count < 2.
[ show source ]
# File lib/facets/core/string/brief.rb, line 10 def brief(string, count = 128, force_cutoff = false, ellipsis="...") return nil unless string return nil if count < 2 if string.size > count cut_at = force_cutoff ? count : (string.index(' ', count-1) || count) xstring = string.slice(0, cut_at) return xstring.chomp(" ") + ellipsis else return string end end
Upacks string ginto bytes.
[ show source ]
# File lib/facets/core/string/bytes.rb, line 6 def bytes self.unpack('C*') end
Converts a string to camelcase. By default capitalization occurs on whitespace and underscores. By setting the first parameter to true the first character can also be captizlized. The second parameter can be assigned a valid Regualr Expression characeter set to determine which characters to match for capitalizing subsequent parts of the string.
"this_is a test".camelcase #=> "thisIsATest" "this_is a test".camelcase(true) #=> "ThisIsATest" "this_is a test".camelcase(true, ' ') #=> "This_isATest"
[ show source ]
# File lib/facets/core/string/camelcase.rb, line 16 def camelcase( first=false, on='_\s' ) if first gsub(/(^|[#{on}]+)([A-Za-z])/){ $2.upcase } else gsub(/([#{on}]+)([A-Za-z])/){ $2.upcase } end end
Variation of coverting a string to camelcase. This is unlike camelcase in that it is geared toward code reflection use.
"this/is_a_test".camelize #=> This::IsATest
[ show source ]
# File lib/facets/core/string/camelize.rb, line 9 def camelize #to_s.gsub(/(^|_)(.)/){$2.upcase} to_s.gsub(/\/(.?)/){ "::" + $1.upcase }.gsub(/(^|_)(.)/){ $2.upcase } end
Return true if the string is capitalized, otherwise false.
"THIS".capitalized? #=> true "This".capitalized? #=> true "this".capitalized? #=> false
[ show source ]
# File lib/facets/core/string/capitalized.rb, line 13 def capitalized? self =~ /^[A-Z]/ end
Returns an array of characters.
"abc".chars #=> ["a","b","c"]
[ show source ]
# File lib/facets/core/string/chars.rb, line 8 def chars self.split(//) end
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
[ show source ]
# File lib/facets/core/string/cmp.rb, line 12 def cmp(other) return -1 if length < other.length return 1 if length > other.length self <=> other # alphabetic compare end
[ show source ]
# File lib/facets/core/string/dequote.rb, line 3 def dequote s = self.dup case self[0,1] when "'", '"', '`' s[0] = '' end case self[-1,1] when "'", '"', '`' s[-1] = '' end s end
Return true if the string is lowercase (downcase), otherwise false.
"THIS".downcase? #=> false "This".downcase? #=> false "this".downcase? #=> true
[ show source ]
# File lib/facets/core/string/downcase.rb, line 12 def downcase? downcase == self end
Scramble the inner characters of words leaving the text still readable (research at Cambridge University, code by KurtDresner).
For example, the above text may result in:
Srblamce the iennr cchrteaars of wodrs lvenaig the txet stlil rbeaadle (rreceash at Cbamigdre Uverintisy, cdoe by KrneruestDr?)
[ show source ]
# File lib/facets/core/string/dresner.rb, line 12 def dresner self.gsub(/\B\w+\B/){$&.split(//).sort_by{rand}} end
Inplace version of dresner method.
[ show source ]
# File lib/facets/core/string/dresner.rb, line 18 def dresner! self.replace(dresner) end
Iterates through each character.
[ show source ]
# File lib/facets/core/string/each_char.rb, line 5 def each_char # :yield: split(//).each { |c| yield( c ) } end
Iterate through each word of a string.
"a string".each_word { |word, range| ... }
[ show source ]
# File lib/facets/core/string/each_word.rb, line 8 def each_word( &yld ) rest_of_string = self wordfind = /([-'\w]+)/ arity = yld.arity offset = 0 while wmatch = wordfind.match(rest_of_string) word = wmatch[0] range = offset+wmatch.begin(0) ... offset+wmatch.end(0) rest_of_string = wmatch.post_match if arity == 1 yld.call(word) else yld.call(word, range) end offset = self.length - rest_of_string.length end end
[ show source ]
# File lib/facets/core/string/starts_with.rb, line 11 def ends_with?(str) self.rindex( str ) == self.length - str.length end
[ show source ]
# File lib/facets/core/enumerable/entropy.rb, line 27 def entropy self.split(//).entropy end
Returns the first separation of a string. Default seperation is by character.
"Hello World".first #=> "H" "Hello World".first(' ') #=> "Hello"
[ show source ]
# File lib/facets/core/string/first.rb, line 14 def first(separator_pattern=//) pattern = self.class.patterns(separator_pattern) split(separator_pattern).at(0) end
Removes the first separation from a string. Defualt separation is by characters.
a = "Hello World" a.first! #=> "H" a #=> "ello World" a = "Hello World" a.first!(' ') #=> "Hello" a #=> "World"
[ show source ]
# File lib/facets/core/string/first.rb, line 36 def first!(separator_pattern=//) pattern = self.class.patterns(separator_pattern) a = shatter(pattern) r = a.first a.shift a.shift replace( a.join('') ) return r end
Prepends to a string.
"Hello World".first = "Hello," #=> "Hello, Hello World"
[ show source ]
# File lib/facets/core/string/first.rb, line 52 def first=( x ) insert(0, x.to_s) end
Returns first n characters.
"Hello World".first_char(3) #=> "Hel"
[ show source ]
# File lib/facets/core/string/first_char.rb, line 8 def first_char(n=1) slice(0, n.to_i) end
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. "
[ show source ]
# File lib/facets/core/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
[ show source ]
# File lib/facets/core/string/format.rb, line 4 def format( *args ) self.%(args) end
[ show source ]
# File lib/facets/core/string/frequency.rb, line 7 def frequency(*args) to_arr(*args).frequency end
Alias for similarity
Replaces underscores with spaces and capitalizes word.
[ show source ]
# File lib/facets/core/string/humanize.rb, line 6 def humanize self.gsub(/_/, " ").capitalize end
[ show source ]
# File lib/facets/core/string/indent.rb, line 25 def indent(n) if n >= 0 gsub(/^/, ' ' * n) else gsub(/^ {0,#{-n}}/, "") end end
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]
[ show source ]
# File lib/facets/core/string/index_all.rb, line 10 def index_all(s, reuse=false) ia = []; i = 0 while (i = self.index(s,i)) ia << i i += (reuse ? 1 : $~.length) end ia end
Returns the last separation of a string. Default separation is by character.
"Hello World".last(' ') #=> "World"
[ show source ]
# File lib/facets/core/string/last.rb, line 13 def last(separator_pattern=//) pattern = self.class.patterns(separator_pattern) self.split(separator_pattern).at(-1) end
Removes the last separation from a string. Default seperation is by characeter.
a = "Hello World" a.last! #=> "d" a #=> "Hello Worl" a = "Hello World" a.last!(' ') #=> "World" a #=> "Hello"
[ show source ]
# File lib/facets/core/string/last.rb, line 43 def last!(separator_pattern=//) pattern = self.class.patterns(separator_pattern) a = shatter(pattern) r = a.last a.pop a.pop replace( a.join('') ) return r end
Appends to a string.
"Hello World".last = ", Bye." #=> "Hello World, Bye."
[ show source ]
# File lib/facets/core/string/last.rb, line 22 def last=(str) self << str end
Returns last n characters.
"Hello World".last_char(3) #=> "rld"
[ show source ]
# File lib/facets/core/string/last_char.rb, line 8 def last_char(n=1) n = n.to_i return self if n > size slice(-n, n) #self[-n..-1] end
Line wrap at width.
puts "1234567890".line_wrap(5)
produces
12345 67890
[ show source ]
# File lib/facets/core/string/line_wrap.rb, line 13 def line_wrap(width) s = gsub(/\t/,' '*4) # tabs default to 4 spaces. s = s.gsub(/\n/,' ') r = s.scan( /.{1,#{width}}/ ) r.join("\n") << "\n" end
Returns an array of characters.
"abc\n123".lines #=> ["abc","123"]
[ show source ]
# File lib/facets/core/string/lines.rb, line 8 def lines self.split(/\n/) end
Alias for downcase?
Provides a margin controlled string.
x = %Q{ | This | is | margin controlled! }.margin
[ show source ]
# File lib/facets/core/string/margin.rb, line 15 def margin(n=0) d = /\A.*\n\s*(.)/.match( self )[1] d = /\A\s*(.)/.match( self)[1] unless d return '' unless d if n == 0 gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, '') else gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, ' ' * n) end end
Converts a string into a valid ruby method name This method is geared toward code reflection.
"MyModule::MyClass".methodize #=> "my_module__my_class"
See also String#modulize, String#pathize
TODO
- Make sure that all scenarios return a valid ruby class name
- Make sure it is revertible
[ show source ]
# File lib/facets/core/string/methodize.rb, line 18 def methodize to_s.gsub(/([A-Z])/, '_\1').downcase.gsub(/^_/,'').gsub(/(::|\/)_?/, '__') end
Converts a string into a valid ruby class or module name This method is geared toward code reflection.
"my_module__my_path".modulize #=> "MyModule::MyPath"
See also String#methodize, String#pathize
TODO
- Make sure that all scenarios return a valid ruby class name
- Make sure it is revertible
[ show source ]
# File lib/facets/core/string/modulize.rb, line 16 def modulize to_s.gsub(/(__|\/)(.?)/){ "::" + $2.upcase }.gsub(/(^|_)(.)/){ $2.upcase } end
Like scan but returns MatchData ($~) rather then matched string ($&).
[ show source ]
# File lib/facets/core/string/mscan.rb, line 7 def mscan(re) #:yield: if block_given? scan(re) { yield($~) } else m = [] scan(re) { m << $~ } m end end
‘Natural order’ comparison of two 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
[ show source ]
# File lib/facets/core/string/natcmp.rb, line 42 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
Retrns 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.
[ show source ]
# File lib/facets/core/string/nchar.rb, line 11 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
[ show source ]
# File lib/facets/core/string/ordinal.rb, line 4 def ordinal self.to_i.ordinal end
Converts a string into a unix path. This method is geared toward code reflection.
See : String#modulize, String#methodize
"MyModule::MyClass".pathize #=> my_module/my_class "my_module__my_class".pathize #=> my_module/my_class
TODO :
- Make sure that all scenarios return a valid unix path
- Make sure it is revertible
[ show source ]
# File lib/facets/core/string/pathize.rb, line 17 def pathize to_s.gsub(/([A-Z])/, '_\1').downcase.gsub(/^_/,'').gsub(/(::|__)_?/, '/') end
Convert an English word from singular to plurel.
"boy".plural #=> boys "tomato".plural #=> tomatoes
[ show source ]
# File lib/facets/core/string/singular.rb, line 76 def plural result = self.to_s.dup String::PLURAL_RULES.each do |(rule, replacement)| break if result.gsub!(rule, replacement) end return result end
Alias for plural
Polymorphic with Array of characters.
[ show source ]
# File lib/facets/core/string/pop.rb, line 5 def pop return '' if size == 0 r = self[-1,1] self[-1] = '' r #self end
Like push but works from the other end of the string.
[ show source ]
# File lib/facets/core/string/pot.rb, line 6 def pot( str=' ' ) insert(0, str) end
[ show source ]
# File lib/facets/core/string/probability.rb, line 7 def probability(*args) to_arr(*args).probability end
Same as shift.
[ show source ]
# File lib/facets/core/string/pull.rb, line 3 def pull return '' if size == 0 self[0] = '' self end
Polymorphic with Array of characters.
[ show source ]
# File lib/facets/core/string/push.rb, line 5 def push(str=' ') concat(str) end
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\""
[ show source ]
# File lib/facets/core/string/quote.rb, line 11 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
Return a random byte of self.
"Ruby rules".rand_byte #=> 121
[ show source ]
# File lib/facets/core/string/rand_byte.rb, line 8 def rand_byte self[rand( size )] end
Destructive rand_byte. Delete a random byte of self and return it.
s = "Ruby rules" s.rand_byte! #=> 121 s #=> "Rub rules"
[ show source ]
# File lib/facets/core/string/rand_byte.rb, line 18 def rand_byte! i = rand( size ) rv = self[i,1] self[i,1] = '' rv end
Return a random string index.
"Ruby rules".rand_index #=> 3
[ show source ]
# File lib/facets/core/string/rand_index.rb, line 6 def rand_index rand( size ) end
Like index but returns a Range.
"This is a test!".range('test') #=> 10..13
[ show source ]
# File lib/facets/core/string/range.rb, line 8 def range(s, offset=0) if self.index(s, offset) return ($~.begin(0))..($~.end(0)-1) end nil end
Like index_all but returns an array of Ranges.
"abc123abc123".range_all('abc') #=> [0..2, 6..8]
[ show source ]
# File lib/facets/core/string/range_all.rb, line 12 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
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]
[ show source ]
# File lib/facets/core/string/range_of_line.rb, line 10 def range_of_line offset=0; charmap = [] self.each do |line| charmap << (offset..(offset + line.length - 1)) offset += line.length end charmap end
Escape string for Regexp use.
[ show source ]
# File lib/facets/core/string/regesc.rb, line 5 def regesc Regexp.escape( self ) end
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>"]
[ show source ]
# File lib/facets/core/string/shatter.rb, line 14 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
Escape special characters used in most unix shells to use it, eg. with system().
[ show source ]
# File lib/facets/core/string/shell_escape.rb, line 7 def shell_escape self.gsub(/([\\\t\| &`<>)('"])/) { |s| '\\' << s } end
[ show source ]
# File lib/facets/core/string/shift.rb, line 2 def shift return '' if size == 0 self[0] = '' self end
Return the string with seperated sections arranged in a random order. The default seperation is by character.
"Ruby rules".shuffle #=> "e lybRsuur"
[ show source ]
# File lib/facets/core/string/shuffle.rb, line 10 def shuffle(separator=//) split(separator).shuffle.join('') end
In place version of shuffle.
[ show source ]
# File lib/facets/core/string/shuffle.rb, line 16 def shuffle!(separator=//) self.replace( shuffle(separator) ) end
A fuzzy matching mechanism. Returns a score from 0-1, based on the number of shared edges. To be effective, the strings must be of length 2 or greater.
"Alexsander".fuzzy_match( "Aleksander" ) #=> 0.9
The way it works:
- Converts each string into a "graph like" object, with edges
"alexsander" -> [ alexsander, alexsand, alexsan ... lexsand ... san ... an, etc ] "aleksander" -> [ aleksander, aleksand ... etc. ]
- Perform match, then remove any subsets from this matched set (i.e. a hit on
"san" is a subset of a hit on "sander")
Above example, once reduced -> [ ale, sander ]
- See’s how many of the matches remain, and calculates a score based on how many matches, their length, and compare to the length of the larger of the two words.
[ show source ]
# File lib/facets/core/string/similarity.rb, line 25 def similarity( str_in ) return 0 if str_in == nil return 1 if self == str_in # Make a graph of each word (okay, so its not a true graph, but is similar) graph_A = Array.new graph_B = Array.new # "graph" self last = self.length (0..last).each do |ff| loc = self.length break if ff == last - 1 wordB = (1..(last-1)).to_a.reverse! if (wordB != nil) wordB.each do |ss| break if ss == ff graph_A.push( "#{self[ff..ss]}" ) end end end # "graph" input string last = str_in.length (0..last).each{ |ff| loc = str_in.length break if ff == last - 1 wordB = (1..(last-1)).to_a.reverse! wordB.each do |ss| break if ss == ff graph_B.push( "#{str_in[ff..ss]}" ) end } # count how many of these "graph edges" we have that are the same matches = graph_A & graph_B #matches = Array.new #graph_A.each do |aa| # matches.push( aa ) if( graph_B.include?( aa ) ) #end # For eliminating subsets, we want to start with the smallest hits. matches.sort!{|x,y| x.length <=> y.length} # eliminate any subsets mclone = matches.dup mclone.each_index do |ii| reg = Regexp.compile( mclone[ii] ) count = 0.0 matches.each{|xx| count += 1 if xx =~ reg} matches.delete(mclone[ii]) if count > 1 end score = 0.0 matches.each{ |mm| score += mm.length } self.length > str_in.length ? largest = self.length : largest = str_in.length return score/largest end
Convert an English word from plurel to singular.
"boys".singular #=> boy "tomatoes".singular #=> tomato
[ show source ]
# File lib/facets/core/string/singular.rb, line 63 def singular result = self.to_s.dup String::SINGULAR_RULES.each do |(rule, replacement)| break if result.gsub!(rule, replacement) end return result end
Alias for singular
Implementation of the soundex algorithm as described by Knuth in volume 3 of The Art of Computer Programming. Returns nil if the value couldn’t be calculated b/c of empty-string or invalid character.
"Ruby".soundex #=> "R100"
[ show source ]
# File lib/facets/core/string/soundex.rb, line 14 def soundex return nil if self.empty? str = self.upcase last_code = String.soundex_code(str[0,1]) soundex_code = str[0,1] for index in 1...(str.size) do return soundex_code if soundex_code.size == 4 code = String.soundex_code(str[index,1]) if code == "0" then last_code = nil elsif code == nil then return nil elsif code != last_code then soundex_code += code last_code = code end end return soundex_code + "000"[0,4-soundex_code.size] end
[ show source ]
# File lib/facets/core/string/starts_with.rb, line 7 def starts_with?(str) self.index( str ) == 0 end
Allows succ to take n step increments.
"abc".succ #=> "abd" "abc".succ(4) #=> "abg" "abc".succ(24) #=> "aca"
[ show source ]
# File lib/facets/core/string/succ.rb, line 9 def succ(n=1) s = self n.times { s = s.succ_once } s end
Aligns each line n spaces. (This used to be taballto.)
[ show source ]
# File lib/facets/core/string/indent.rb, line 7 def tab(n) gsub(/^ */, ' ' * n) end
Preserves relative tabbing. The first non-empty line ends up with n spaces before nonspace.
[ show source ]
# File lib/facets/core/string/indent.rb, line 14 def tabto(n) if self =~ /^( *)\S/ indent(n - $1.length) else self end end
Essentially makes to_a an alias for split, with the excpetion that if no divider is given then the array is split on charaters, and NOT on the global input record divider ($/).
WARNING There is a slight chance of incompatability with other libraries which depend on spliting with $/ (although doing so is a very bad idea!).
[ show source ]
# File lib/facets/core/string/to_a.rb, line 14 def to_a(div=//,limit=0) split(div,limit) end
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
[ show source ]
# File lib/facets/core/string/to_b.rb, line 17 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
Get a constant by a given string name.
"Class".to_const #=> Class
Note this method is not as verstile as it should be, since it can not access contants relative to the current execution context. But without a binding_of_caller that does not seem possible.
[ show source ]
# File lib/facets/core/string/to_const.rb, line 12 def to_const split('::').inject(Object){ |namespace,name| namespace.const_get(name) } end
[ show source ]
# File lib/facets/core/string/to_date.rb, line 4 def to_date require 'date' require 'parsedate' ::Date::civil(*ParseDate.parsedate(self)[0..2]) end
[ show source ]
# File lib/facets/core/string/to_proc.rb, line 14 def to_proc(context=nil) if context if context.kind_of?(Binding) or context.kind_of?(Proc) Kernel.eval "proc { #{self} }", context else context context.instance_eval "proc { #{self} }" end else Kernel.eval "proc { #{self} }" end end
Turns a string into a regular expression. By default it will escape all characters. Use false argument to turn off escaping.
"[".to_re #=> /\[/
[ show source ]
# File lib/facets/core/string/to_re.rb, line 10 def to_re(esc=true) Regexp.new((esc ? Regexp.escape(self) : self)) end
Turns a string into a regular expression. Unlike to_re this will not escape characters.
"a?".to_rx #=> /a?/
[ show source ]
# File lib/facets/core/string/to_re.rb, line 19 def to_rx Regexp.new(self) end
[ show source ]
# File lib/facets/core/string/to_time.rb, line 4 def to_time require 'time' Time.parse(self) end
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!"
[ show source ]
# File lib/facets/core/string/unbracket.rb, line 16 def unbracket(bra=nil, ket=nil) if bra ket = Sring.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 = String.bra2ket[ self[0,1] ] return self.slice(1...-1) if self[-1,1] == m end end return self.dup # if nothing else end
Inplace version of debraket.
[ show source ]
# File lib/facets/core/string/unbracket.rb, line 33 def unbracket!(bra=nil, ket=nil) self.replace( unbracket(bra, ket) ) end
Underscore string based on camelcase characteristics.
[ show source ]
# File lib/facets/core/string/underscore.rb, line 5 def underscore #(camel_cased_word) self.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase end
Common Unix cryptography method.
[ show source ]
# File lib/facets/core/string/unix_crypt.rb, line 7 def unix_crypt self.crypt(String.rand_letter + String.rand_letter) end
Common Unix cryptography in-place method.
[ show source ]
# File lib/facets/core/string/unix_crypt.rb, line 12 def unix_crypt! self.replace( unix_crypt ) end
Upack with offset. Extends unpack to allow a string to be unpacked starting at an offset position within it.
[ show source ]
# File lib/facets/core/string/unpack.rb, line 8 def unpack(format, offset=nil) if offset.nil? unpack_from_orgin(format) else self[offset..-1].unpack_from_orgin(format) end end
[ show source ]
# File lib/facets/core/string/unshift.rb, line 4 def unshift( str=' ' ) insert(0, str) end
Is the string upcase/uppercase?
"THIS".upcase? #=> true "This".upcase? #=> false "this".upcase? #=> false
[ show source ]
# File lib/facets/core/string/upcase.rb, line 13 def upcase? self.upcase == self end
Alias for upcase?
Alias for blank?
Alias for blank?
Filters out words from a string based on block test.
"a string".word_filter { |word| word =~ /^a/ } #=> "string"
[ show source ]
# File lib/facets/core/string/word_filter.rb, line 8 def word_filter( &blk ) s = self.dup s.word_filter!( &blk ) end
In place version of word_filter.
"a string".word_filter { |word| ... }
[ show source ]
# File lib/facets/core/string/word_filter.rb, line 17 def word_filter! #:yield: rest_of_string = self wordfind = /(\w+)/ offset = 0 while wmatch = wordfind.match(rest_of_string) word = wmatch[0] range = offset+wmatch.begin(0) ... offset+wmatch.end(0) rest_of_string = wmatch.post_match self[range] = yield( word ).to_s offset = self.length - rest_of_string.length end self end
Word wrap a string not exceeding max width.
puts "this is a test".word_wrap(4)
produces
this is a test
[ show source ]
# File lib/facets/core/string/word_wrap.rb, line 18 def word_wrap( col_width=80 ) self.dup.word_wrap!( col_width ) end
As with word_wrap, but modifies the string in place.
[ show source ]
# File lib/facets/core/string/word_wrap.rb, line 24 def word_wrap!( col_width=80 ) self.gsub!( /(\S{#{col_width}})(?=\S)/, '\1 ' ) self.gsub!( /(.{1,#{col_width}})(?:\s+|$)/, "\\1\n" ) self end
Returns an array of characters.
"abc 123".words #=> ["abc","123"]
[ show source ]
# File lib/facets/core/string/words.rb, line 8 def words self.split(/\s+/) end