Class: String
- Includes:
- Random::StringExtensions
- Defined in:
- lib/core/facets/string/natcmp.rb,
lib/core/facets/boolean.rb,
lib/standard/facets/date.rb,
lib/core/facets/string/tab.rb,
lib/core/facets/string/xor.rb,
lib/standard/facets/random.rb,
lib/core/facets/string/file.rb,
lib/core/facets/string/fold.rb,
lib/core/facets/kernel/blank.rb,
lib/core/facets/string/align.rb,
lib/core/facets/string/bytes.rb,
lib/core/facets/string/lines.rb,
lib/core/facets/string/mscan.rb,
lib/core/facets/string/nchar.rb,
lib/core/facets/string/quote.rb,
lib/core/facets/string/range.rb,
lib/core/facets/string/store.rb,
lib/core/facets/string/tabto.rb,
lib/core/facets/string/to_re.rb,
lib/core/facets/string/words.rb,
lib/core/facets/string/cleave.rb,
lib/core/facets/string/divide.rb,
lib/core/facets/string/indent.rb,
lib/core/facets/string/lchomp.rb,
lib/core/facets/string/margin.rb,
lib/core/facets/string/op_div.rb,
lib/core/facets/string/op_sub.rb,
lib/core/facets/string/splice.rb,
lib/core/facets/string/squish.rb,
lib/core/facets/string/unfold.rb,
lib/supplemental/facets/tuple.rb,
lib/core/facets/comparable/cmp.rb,
lib/core/facets/string/bracket.rb,
lib/core/facets/string/exclude.rb,
lib/core/facets/string/pathize.rb,
lib/core/facets/string/rewrite.rb,
lib/core/facets/string/shatter.rb,
lib/core/facets/string/modulize.rb,
lib/core/facets/string/newlines.rb,
lib/core/facets/string/camelcase.rb,
lib/core/facets/string/each_char.rb,
lib/core/facets/string/each_word.rb,
lib/core/facets/string/index_all.rb,
lib/core/facets/string/line_wrap.rb,
lib/core/facets/string/methodize.rb,
lib/core/facets/string/snakecase.rb,
lib/core/facets/string/titlecase.rb,
lib/core/facets/string/uppercase.rb,
lib/core/facets/string/word_wrap.rb,
lib/core/facets/string/characters.rb,
lib/core/facets/string/cleanlines.rb,
lib/core/facets/string/expand_tab.rb,
lib/core/facets/string/similarity.rb,
lib/core/facets/string/start_with.rb,
lib/core/facets/string/underscore.rb,
lib/core/facets/string/variablize.rb,
lib/core/facets/string/capitalized.rb,
lib/core/facets/string/interpolate.rb,
lib/core/facets/object/object_state.rb,
lib/core/facets/string/edit_distance.rb,
lib/core/facets/string/random_binary.rb,
lib/core-uncommon/facets/string/crypt.rb,
lib/core/facets/string/compress_lines.rb,
lib/core-uncommon/facets/integer/roman.rb,
lib/core-uncommon/facets/string/acronym.rb
Overview
–
Developer’s Notes
Old definition of start_with? written by Lucas Carlson and Blaine Cook was …
index(prefix) == 0
I like the simplicity of this definition, but I could not find a way define #end_with? in similar terms and still accept regular expressions for the suffix. So I had to use Regexp match. On th upside, we can get MatchData which might be more useful. ++
Constant Summary collapse
- BRA2KET =
{ '['=>']', '('=>')', '{'=>'}', '<'=>'>' }
- ROMAN =
Taken from O’Reilly’s Perl Cookbook 6.23. Regular Expression Grabbag.
/^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i- ROMAN_VALUES =
Integer::ROMAN_VALUES.inject({}) do |h,(r,a)| h[r] = a; h end
Class Method Summary collapse
-
.interpolate(&str) ⇒ Object
Interpolate.
-
.random_binary(n_bytes) ⇒ Object
Generate a random binary string of
n_bytessize.
Instance Method Summary collapse
-
#-(pattern) ⇒ Object
Removes occurances of a string or regexp.
-
#/(path) ⇒ Object
Treats
selfandpathas representations of pathnames, joining thme together as a single path. -
#^(aString) ⇒ Object
Binary XOR of two strings.
- #_crypt ⇒ Object
-
#acronymize ⇒ Object
CREDIT: Robert Fey.
-
#align(direction, n, sep = "\n", c = ' ') ⇒ Object
Alignment method dispatches to #align_right, #align_left or #align_center, accorging to the first
directionparameter. -
#align_center(n, sep = "\n", c = ' ') ⇒ Object
Centers each line of a string.
-
#align_left(n, sep = "\n", c = ' ') ⇒ Object
Align a string to the left.
-
#align_right(n, sep = "\n", c = ' ') ⇒ Object
Align a string to the right.
-
#blank? ⇒ Boolean
Is this string just whitespace?.
-
#bracket(bra, ket = nil) ⇒ Object
Return a new string embraced by given brackets.
-
#bracket!(bra, ket = nil) ⇒ Object
Inplace version of #bracket.
-
#bytes(&blk) ⇒ Object
Upacks string into bytes.
- #camelcase(first_letter = nil) ⇒ Object
-
#capitalized? ⇒ Boolean
Return true if the string is capitalized, otherwise false.
-
#characters ⇒ Object
Returns an array of characters.
-
#cleanlines(&block) ⇒ Object
Returns an Enumerator for iterating over each line of the string, stripped of whitespace on either side.
-
#cleave(threshold = nil, len = nil) ⇒ Object
Cleave a string.
-
#cmp(other) ⇒ Object
Compare method that takes length into account.
-
#compress_lines(spaced = true) ⇒ Object
Matches any whitespace (including newline) and replaces with a single space.
-
#crypt(salt = nil) ⇒ Object
Common Unix cryptography method.
-
#divide(re) ⇒ Object
Breaks a string up into an array based on a regular expression.
-
#downcase? ⇒ Boolean
Return true if the string is lowercase (downcase), otherwise false.
-
#each_char ⇒ Object
Yields a single-character string for each character in the string.
-
#each_word(&block) ⇒ Object
Iterate through each word of a string.
-
#edit_distance(str2) ⇒ Object
Levenshtein distance algorithm implementation for Ruby, with UTF-8 support.
-
#end_with?(suffix) ⇒ Boolean
(also: #ends_with?)
Does a string end with the given suffix?.
-
#exclude?(str) ⇒ Boolean
The inverse of include?.
-
#expand_tabs(n = 8) ⇒ Object
(also: #expand_tab)
Expands tabs to
nspaces. -
#file ⇒ Object
Use fluent notation for making file directives.
-
#fold(ignore_indented = false) ⇒ Object
Returns a new string with all new lines removed from adjacent lines of text.
-
#indent(n, c = ' ') ⇒ Object
Indent left or right by n spaces.
-
#indent!(n, c = ' ') ⇒ Object
Equivalent to String#indent, but modifies the receiver in place.
-
#index_all(s, reuse = false) ⇒ Object
Like index but returns an array of all index locations.
- #inter_camelcase ⇒ Object
-
#lchomp(match) ⇒ Object
Left chomp.
-
#lchomp!(match) ⇒ Object
In-place left chomp.
-
#line_wrap(width, tabs = 4) ⇒ Object
Line wrap at width.
-
#lines(&blk) ⇒ Object
Returns an array of characters.
- #lower_camelcase ⇒ Object
-
#lowercase ⇒ Object
Downcase first letter.
-
#margin(n = 0) ⇒ Object
Provides a margin controlled string.
-
#methodize ⇒ Object
Translate a (class or module) name to a suitable method name.
-
#modulize ⇒ Object
Converts a string to module name representation.
-
#mscan(re) ⇒ Object
Like #scan but returns MatchData ($~) rather then matched string ($&).
-
#natcmp(str2, caseInsensitive = false) ⇒ Object
‘Natural order’ comparison of strings, e.g.
-
#nchar(n, replacement = nil) ⇒ Object
Returns n characters of the string.
-
#newlines(&block) ⇒ Object
Returns an Enumerator for iterating over each line of the string, void of the termining newline character, in contrast to #lines which retains it.
- #object_state(data = nil) ⇒ Object
-
#pathize ⇒ Object
Converts a camelcase name (e.g. class or module name) to a unix path.
-
#quote(type = :double, count = nil) ⇒ Object
Return a new string embraced by given
typeandcountof quotes. -
#range(pattern, offset = 0) ⇒ Object
Like #index but returns a Range.
-
#range_all(pattern, reuse = false) ⇒ Object
Like #index_all but returns an array of Ranges.
-
#range_of_line ⇒ Object
Returns an array of ranges mapping the characters per line.
-
#rewrite(rules) ⇒ Object
Apply a set of rules in the form of regular expression matches to the string.
-
#roman ⇒ Object
Considers string a Roman numeral numeral, and converts it to the corresponding integer.
-
#roman? ⇒ Boolean
Returns true iif the subject is a valid Roman numeral.
-
#shatter(re) ⇒ Object
Breaks a string up into an array based on a regular expression.
-
#similarity(str_in) ⇒ Object
A fuzzy matching mechanism.
-
#snakecase ⇒ Object
The reverse of
camelcase. -
#splice(idx, sub = nil) ⇒ Object
String#slice is essentially the same as #store.
-
#squish ⇒ Object
Returns the string, first removing all whitespace on both ends of the string, and then changing remaining consecutive whitespace groups into one space each.
-
#squish! ⇒ Object
Performs a destructive squish.
-
#start_with?(prefix) ⇒ Boolean
(also: #starts_with?)
Does a string start with the given prefix?.
-
#tab(n) ⇒ Object
Aligns each line n spaces.
-
#tabto(n) ⇒ Object
Preserves relative tabbing.
-
#titlecase ⇒ Object
Title case.
-
#to_b ⇒ Object
Interpret common affirmative string meanings as true, otherwise nil or false.
-
#to_date ⇒ Object
Parse data from string.
-
#to_datetime ⇒ Object
Convert string to DateTime.
-
#to_re(esc = false) ⇒ Object
Turns a string into a regular expression.
-
#to_rx(esc = true) ⇒ Object
Turns a string into a regular expression.
-
#to_t(&yld) ⇒ Object
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.
- #to_time(form = :utc) ⇒ Object
-
#unbracket(bra = nil, ket = nil) ⇒ Object
Return a new string with the given brackets removed.
-
#unbracket!(bra = nil, ket = nil) ⇒ Object
Inplace version of #unbracket.
-
#underscore ⇒ Object
The reverse of
camelcase. -
#unfold ⇒ Object
Unfold paragrpahs.
-
#unindent(size = nil) ⇒ Object
Remove excessive indentation.
-
#unindent! ⇒ Object
Equivalent to String#unindent, but modifies the receiver in place.
-
#unquote ⇒ Object
Remove quotes from string.
-
#upcase? ⇒ Boolean
Is the string upcase/uppercase?.
- #upper_camelcase ⇒ Object
-
#uppercase ⇒ Object
Upcase first letter.
-
#variablize ⇒ Object
Prepend an “@” to the beginning of a string to make a instance variable name.
-
#word_wrap(col_width = 80) ⇒ Object
Word wrap a string not exceeding max width.
-
#word_wrap!(col_width = 80) ⇒ Object
As with #word_wrap, but modifies the string in place.
-
#words ⇒ Object
Returns an array of characters.
Methods included from Random::StringExtensions
#at_rand, #at_rand!, included, #rand_byte, #rand_byte!, #rand_index, #shuffle, #shuffle!
Class Method Details
.interpolate(&str) ⇒ Object
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
14 15 16 |
# File 'lib/core/facets/string/interpolate.rb', line 14 def self.interpolate(&str) eval "%{#{str.call}}", str.binding end |
Instance Method Details
#-(pattern) ⇒ Object
Removes occurances of a string or regexp.
("HELLO HELLO" - "LL") #=> "HEO HEO"
CREDIT: Benjamin David Oakes
9 10 11 |
# File 'lib/core/facets/string/op_sub.rb', line 9 def -(pattern) self.gsub(pattern, '') end |
#/(path) ⇒ Object
Treats self and path as representations of pathnames, joining thme together as a single path.
('home' / 'trans') #=> 'home/trans'
9 10 11 |
# File 'lib/core/facets/string/op_div.rb', line 9 def /(path) File.join(self, path.to_s) end |
#^(aString) ⇒ Object
Binary XOR of two strings.
a = "\000\000\001\001" ^ "\000\001\000\001"
b = "\003\003\003" ^ "\000\001\002"
a #=> "\000\001\001\000"
b #=> "\003\002\001"
11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/core/facets/string/xor.rb', line 11 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 |
#_crypt ⇒ Object
3 |
# File 'lib/core-uncommon/facets/string/crypt.rb', line 3 alias_method :_crypt, :crypt |
#acronymize ⇒ Object
CREDIT: Robert Fey
4 5 6 |
# File 'lib/core-uncommon/facets/string/acronym.rb', line 4 def acronymize gsub(/(([a-zA-Z0-9])([a-zA-Z0-9])*)./,"\\2") end |
#align(direction, n, sep = "\n", c = ' ') ⇒ Object
Alignment method dispatches to #align_right, #align_left or #align_center, accorging to the first direction parameter.
s = <<-EOS
This is a test
and
so on
EOS
s.align(:right, 14)
produces …
This is a test
and
so on
Returns a String aligned right, left or center.
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/core/facets/string/align.rb', line 21 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 = ' ') ⇒ Object
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
s.align_center(14)
produces …
This is a test
and
so on
CREDIT: Trans
116 117 118 119 120 121 122 |
# File 'lib/core/facets/string/align.rb', line 116 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 = ' ') ⇒ Object
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
s.align_left(20, "\n", '.')
produces …
This is a test......
and.................
so on...............
CREDIT: Trans
86 87 88 89 90 91 92 |
# File 'lib/core/facets/string/align.rb', line 86 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 = ' ') ⇒ Object
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
s.align_right(14)
produces …
This is a test
and
so on
CREDIT: Trans
56 57 58 59 60 61 62 |
# File 'lib/core/facets/string/align.rb', line 56 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? ⇒ Boolean
Is this string just whitespace?
"abc".blank? #=> false
" ".blank? #=> true
74 75 76 |
# File 'lib/core/facets/kernel/blank.rb', line 74 def blank? /\S/ !~ self end |
#bracket(bra, ket = nil) ⇒ Object
Return a new string embraced by given brackets. 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
14 15 16 17 18 |
# 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) ⇒ Object
Inplace version of #bracket.
CREDIT: Trans
24 25 26 |
# File 'lib/core/facets/string/bracket.rb', line 24 def bracket!(bra, ket=nil) self.replace(bracket(bra, ket)) end |
#bytes(&blk) ⇒ Object
Upacks string into bytes.
Note, this is not 100% compatible with 1.8.7+ which returns an enumerator instead of an array.
10 11 12 13 14 15 16 |
# 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) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/core/facets/string/camelcase.rb', line 21 def camelcase(first_letter=nil) case first_letter when :lower, true lower_camelcase when :inter, false inter_camelcase else 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 end |
#capitalized? ⇒ Boolean
Return true if the string is capitalized, otherwise false.
"This".capitalized? #=> true
"THIS".capitalized? #=> false
"this".capitalized? #=> false
Note Ruby’s strange concept of capitalized. See capitalcase for the more command conception.
CREDIT: Phil Tomson
14 15 16 |
# File 'lib/core/facets/string/capitalized.rb', line 14 def capitalized? capitalize == self end |
#characters ⇒ Object
Returns an array of characters.
"abc".characters.to_a #=> ["a","b","c"]
TODO: Probably should make this an enumerator. With #scan?
8 9 10 |
# File 'lib/core/facets/string/characters.rb', line 8 def characters split(//) end |
#cleanlines(&block) ⇒ Object
Returns an Enumerator for iterating over each line of the string, stripped of whitespace on either side.
"this\nthat\nother\n".cleanlines.to_a #=> ['this', 'that', 'other']
11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/core/facets/string/cleanlines.rb', line 11 def cleanlines(&block) if block scan(/^.*?$/) do |line| block.call(line.strip) end else str = self Enumerator.new do |output| str.scan(/^.*?$/) do |line| output.yield(line.strip) end end end end |
#cleave(threshold = nil, len = nil) ⇒ Object
Cleave a string. Break a string in two parts at the nearest whitespace.
CREDIT: Trans
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# 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) ⇒ Object
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
TODO: Move String#cmp to string/ directory.
34 35 36 37 38 |
# File 'lib/core/facets/comparable/cmp.rb', line 34 def cmp(other) return -1 if length < other.length return 1 if length > other.length self <=> other # alphabetic compare end |
#compress_lines(spaced = true) ⇒ Object
Matches any whitespace (including newline) and replaces with a single space
string = <<-QUERY.compress_lines
SELECT name
FROM users
QUERY
string #=> "SELECT name FROM users"
12 13 14 |
# File 'lib/core/facets/string/compress_lines.rb', line 12 def compress_lines(spaced = true) split($/).map{ |line| line.strip }.join(spaced ? ' ' : '') end |
#crypt(salt = nil) ⇒ Object
Common Unix cryptography method. This adds a default salt to the built-in crypt method.
NOTE: This is not (presently) a common core extension and is not loaded automatically when using require 'facets'.
11 12 13 14 15 16 17 |
# File 'lib/core-uncommon/facets/string/crypt.rb', line 11 def crypt(salt=nil) salt ||= ( (rand(26) + (rand(2) == 0 ? 65 : 97) ).chr + (rand(26) + (rand(2) == 0 ? 65 : 97) ).chr ) _crypt(salt) end |
#divide(re) ⇒ Object
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( /\<.*?\>/ )
#=> ["<p>This", "<b>is", "</b>a test.", "</p>"]
CREDIT: Trans
12 13 14 15 |
# File 'lib/core/facets/string/divide.rb', line 12 def divide( re ) re2 = /#{re}.*?(?=#{re}|\Z)/ scan(re2) #{re}(?=#{re})/) end |
#downcase? ⇒ Boolean
Return true if the string is lowercase (downcase), otherwise false.
"THIS".downcase? #=> false
"This".downcase? #=> false
"this".downcase? #=> true
CREDIT: Phil Tomson
26 27 28 |
# File 'lib/core/facets/string/capitalized.rb', line 26 def downcase? downcase == self end |
#each_char ⇒ Object
Yields a single-character string for each character in the string. When $KCODE = ‘UTF8’, multi-byte characters are yielded appropriately.
a = ''
"HELLO".each_char{ |c| a << "#{c.downcase}" }
a #=> 'hello'
14 15 16 17 |
# File 'lib/core/facets/string/each_char.rb', line 14 def each_char # :yield: scanner, char = StringScanner.new(self), /./mu loop{ yield(scanner.scan(char) || break) } end |
#each_word(&block) ⇒ Object
Iterate through each word of a string.
a = []
"list of words".each_word { |word| a << word }
a #=> ['list', 'of', 'words']
13 14 15 |
# File 'lib/core/facets/string/each_word.rb', line 13 def each_word(&block) words.each(&block) end |
#edit_distance(str2) ⇒ Object
Levenshtein distance algorithm implementation for Ruby, with UTF-8 support.
The Levenshtein distance is a measure of how similar two strings s and t are, calculated as the number of deletions/insertions/substitutions needed to transform s into t. The greater the distance, the more the strings differ.
The Levenshtein distance is also sometimes referred to as the easier-to-pronounce-and-spell ‘edit distance’.
Calculate the Levenshtein distance between two strings self and str2. self and str2 should be ASCII, UTF-8, or a one-byte-per character encoding such as ISO-8859-*.
The strings will be treated as UTF-8 if $KCODE is set appropriately (i.e. ‘u’). Otherwise, the comparison will be performed byte-by-byte. There is no specific support for Shift-JIS or EUC strings.
When using Unicode text, be aware that this algorithm does not perform normalisation. If there is a possibility of different normalised forms being used, normalisation should be performed beforehand.
CREDIT: Paul Battley
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/core/facets/string/edit_distance.rb', line 25 def edit_distance(str2) str1 = self if $KCODE =~ /^U/i unpack_rule = 'U*' else unpack_rule = 'C*' end s = str1.unpack(unpack_rule) t = str2.unpack(unpack_rule) n = s.length m = t.length return m if (0 == n) return n if (0 == m) d = (0..m).to_a x = nil (0...n).each do |i| e = i+1 (0...m).each do |j| cost = (s[i] == t[j]) ? 0 : 1 x = [ d[j+1] + 1, # insertion e + 1, # deletion d[j] + cost # substitution ].min d[j] = e e = x end d[m] = x end return x end |
#end_with?(suffix) ⇒ Boolean Also known as: ends_with?
Does a string end with the given suffix?
"hello".end_with?("lo") #=> true
"hello".end_with?("to") #=> false
Note: This definition is better than standard Ruby’s becuase it handles regular expressions.
CREDIT: Juris Galang
49 50 51 52 |
# File 'lib/core/facets/string/start_with.rb', line 49 def end_with?(suffix) suffix = Regexp.escape(suffix.to_s) unless Regexp===suffix /#{suffix}$/.match(self) ? true : false end |
#exclude?(str) ⇒ Boolean
The inverse of include?.
5 6 7 |
# File 'lib/core/facets/string/exclude.rb', line 5 def exclude?(str) !include?(str) end |
#expand_tabs(n = 8) ⇒ Object Also known as: expand_tab
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".(2) #=> " Hey"
Thanks to GGaramuno for a more efficient algorithm. Very nice.
CREDIT: Gavin Sinclair, Noah Gibbs, GGaramuno
TODO: Don’t much care for the name String#expand_tabs. What about a more concise name like #detab?
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/core/facets/string/expand_tab.rb', line 16 def (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 |
#file ⇒ Object
Use fluent notation for making file directives.
For instance, if we had a file ‘foo.txt’,
'foo.txt'.file.mtime
11 12 13 |
# File 'lib/core/facets/string/file.rb', line 11 def file Functor.new(&method(:file_send).to_proc) end |
#fold(ignore_indented = false) ⇒ Object
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
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# 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, c = ' ') ⇒ Object
Indent left or right by n spaces. (This used to be called #tab and aliased as #indent.)
CREDIT: Gavin Sinclair, Trans, Tyler Rick
8 9 10 11 12 13 14 |
# File 'lib/core/facets/string/indent.rb', line 8 def indent(n, c=' ') if n >= 0 gsub(/^/, c * n) else gsub(/^#{Regexp.escape(c)}{0,#{-n}}/, "") end end |
#indent!(n, c = ' ') ⇒ Object
Equivalent to String#indent, but modifies the receiver in place.
18 19 20 |
# File 'lib/core/facets/string/indent.rb', line 18 def indent!(n, c=' ') replace(indent(n,c)) end |
#index_all(s, reuse = false) ⇒ Object
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.
14 15 16 17 18 19 20 21 22 |
# File 'lib/core/facets/string/index_all.rb', line 14 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 |
#inter_camelcase ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/core/facets/string/camelcase.rb', line 38 def inter_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 |
#lchomp(match) ⇒ Object
Left chomp.
"help".lchomp("h") #=> "elp"
"help".lchomp("k") #=> "help"
CREDIT: Trans
10 11 12 13 14 15 16 |
# File 'lib/core/facets/string/lchomp.rb', line 10 def lchomp(match) if index(match) == 0 self[match.size..-1] else self.dup end end |
#lchomp!(match) ⇒ Object
In-place left chomp.
"help".lchomp("h") #=> "elp"
"help".lchomp("k") #=> "help"
CREDIT: Trans
25 26 27 28 29 30 |
# File 'lib/core/facets/string/lchomp.rb', line 25 def lchomp!(match) if index(match) == 0 self[0...match.size] = '' self end end |
#line_wrap(width, tabs = 4) ⇒ Object
Line wrap at width.
s = "1234567890".line_wrap(5)
s #=> "12345\n67890\n"
CREDIT: Trans
11 12 13 14 15 16 |
# File 'lib/core/facets/string/line_wrap.rb', line 11 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) ⇒ Object
Returns an array of characters.
"abc\n123".lines.to_a #=> ["abc\n","123"]
9 10 11 12 13 14 15 |
# File 'lib/core/facets/string/lines.rb', line 9 def lines(&blk) if block_given? each_line(&blk) #scan(/$.*?\n/).each(&blk) else Enumerator.new(self, :lines) #.split(/\n/) end end |
#lower_camelcase ⇒ Object
53 54 55 56 57 58 59 |
# File 'lib/core/facets/string/camelcase.rb', line 53 def lower_camelcase #str = dup #str = dup #str.gsub!(/\/(.?)/){ "::#{$1.upcase}" } # NOT SO SURE ABOUT THIS #str.gsub!(/(?:_+|-+)([a-z])/){ $1.upcase } inter_camelcase.gsub(/(\A|\s)([A-Z])/){ $1 + $2.downcase } end |
#lowercase ⇒ Object
Downcase first letter.
17 18 19 20 |
# 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) ⇒ Object
Provides a margin controlled string.
x = %Q{
| This
| is
| margin controlled!
}.margin
NOTE: This may still need a bit of tweaking.
TODO: describe its limits and caveats and edge cases
CREDIT: Trans
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/core/facets/string/margin.rb', line 17 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 ⇒ Object
Translate a (class or module) name to a suitable method name.
"My::CoolClass".methodize #=> "my__cool_class"
– Rails definition …
gsub(/\//, '__').
gsub(/::/, '__').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
++
18 19 20 21 22 23 24 |
# File 'lib/core/facets/string/methodize.rb', line 18 def methodize gsub(/([A-Z]+)([A-Z])/,'\1_\2'). gsub(/([a-z])([A-Z])/,'\1_\2'). gsub('/' ,'__'). gsub('::','__'). downcase end |
#modulize ⇒ Object
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"
– Rails definition …
gsub(/__(.?)/){ "::#{$1.upcase}" }.
gsub(/\/(.?)/){ "::#{$1.upcase}" }.
gsub(/(?:_+)([a-z])/){ $1.upcase }.
gsub(/(^|\s+)([a-z])/){ $1 + $2.upcase }
++
23 24 25 26 27 28 |
# File 'lib/core/facets/string/modulize.rb', line 23 def modulize gsub('__','/'). gsub(/\/(.?)/){ "::#{$1.upcase}" }. gsub(/(?:_+|-+)([a-z])/){ $1.upcase }. gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase } end |
#mscan(re) ⇒ Object
Like #scan but returns MatchData ($~) rather then matched string ($&).
CREDIT: Trans
8 9 10 11 12 13 14 15 16 |
# 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) ⇒ Object
‘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.1".natcmp("Hello.10") #=> -1
TODO: Invert case flag?
CREDIT: Alan Davies, Martin Pool
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/core/facets/string/natcmp.rb', line 45 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 |
#nchar(n, replacement = nil) ⇒ Object
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.
str = "this is text"
str.nchar(4) #=> "this"
str.nchar(-4) #=> "text"
Alternatively a replacement string can be given, which will replace the n characters.
str.nchar(4, 'that') #=> "that is text"
The original string remains unaffected.
str #=> "this is text"
21 22 23 24 25 26 27 28 29 |
# File 'lib/core/facets/string/nchar.rb', line 21 def nchar(n, replacement=nil) if replacement s = self.dup n > 0 ? (s[0...n] = replacement) : (s[n..-1] = replacement) s else n > 0 ? self[0...n] : self[n..-1] end end |
#newlines(&block) ⇒ Object
Returns an Enumerator for iterating over each line of the string, void of the termining newline character, in contrast to #lines which retains it.
"a\nb\nc".newlines.class.assert == Enumerator
"a\nb\nc".newlines.to_a.assert == %w{a b c}
a = []
"a\nb\nc".newlines{|nl| a << nl}
a.assert == %w{a b c}
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/core/facets/string/newlines.rb', line 16 def newlines(&block) if block scan(/^.*?$/) do |line| block.call(line.chomp) end else str = self Enumerator.new do |output| str.scan(/^.*?$/) do |line| output.yield(line.chomp) end end end end |
#object_state(data = nil) ⇒ Object
54 55 56 |
# File 'lib/core/facets/object/object_state.rb', line 54 def object_state(data=nil) data ? replace(data) : dup end |
#pathize ⇒ Object
Converts a camelcase name (e.g. class or module name) to a unix path.
"ExamplePathize".pathize #=> "example_pathize"
"ExamplePathize::Example".pathize #=> "example_pathize/example"
8 9 10 11 12 13 14 |
# File 'lib/core/facets/string/pathize.rb', line 8 def pathize gsub(/([A-Z]+)([A-Z])/,'\1_\2'). gsub(/([a-z])([A-Z])/,'\1_\2'). gsub('__','/'). gsub('::','/'). downcase end |
#quote(type = :double, count = nil) ⇒ Object
Return a new string embraced by given type and count of quotes. The arguments can be given in any order.
If no type is given, double quotes are assumed.
"quote me".quote #=> '"quote me"'
If no type but a count is given then :mixed is assumed.
"quote me".quote(1) #=> %q{'quote me'}
"quote me".quote(2) #=> %q{"quote me"}
"quote me".quote(3) #=> %q{'"quote me"'}
Symbols can be used to describe the type.
"quote me".quote(:single) #=> %q{'quote me'}
"quote me".quote(:double) #=> %q{"quote me"}
"quote me".quote(:back) #=> %q{`quote me`}
"quote me".quote(:bracket) #=> %q{`quote me'}
Or the character itself.
"quote me".quote("'") #=> %q{'quote me'}
"quote me".quote('"') #=> %q{"quote me"}
"quote me".quote("`") #=> %q{`quote me`}
"quote me".quote("`'") #=> %q{`quote me'}
CREDIT: Trans
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/core/facets/string/quote.rb', line 32 def quote(type=:double, count=nil) if Integer === type tmp = count count = type type = tmp || :mixed else count ||= 1 end type = type.to_s unless Integer===type case type when "'", 'single', 's', 1 f = "'" * count b = f when '"', 'double', 'd', 2 f = '"' * count b = f when '`', 'back', 'b', -1 f = '`' * count b = f when "`'", 'bracket', 'sb' f = "`" * count b = "'" * count when "'\"", 'mixed', "m", Integer c = (count.to_f / 2).to_i f = '"' * c b = f if count % 2 != 0 f = "'" + f b = b + "'" end else raise ArgumentError, "unrecognized quote type -- #{type}" end "#{f}#{self}#{b}" end |
#range(pattern, offset = 0) ⇒ Object
Like #index but returns a Range.
"This is a test!".range('test') #=> (10..13)
CREDIT: Trans
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/core/facets/string/range.rb', line 9 def range(pattern, offset=0) unless Regexp === pattern pattern = Regexp.new(Regexp.escape(pattern.to_s)) end string = self[offset..-1] if md = pattern.match(string) return (md.begin(0)+offset)..(md.end(0)+offset-1) end nil end |
#range_all(pattern, reuse = false) ⇒ Object
Like #index_all but returns an array of Ranges.
"abc123abc123".range_all('abc') #=> [0..2, 6..8]
TODO: Add offset ?
CREDIT: Trans
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/core/facets/string/range.rb', line 28 def range_all(pattern, reuse=false) r = []; i = 0 while i < self.length rng = range(pattern, i) if rng r << rng i += reuse ? 1 : rng.end + 1 else break end end r.uniq end |
#range_of_line ⇒ Object
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
50 51 52 53 54 55 56 57 |
# File 'lib/core/facets/string/range.rb', line 50 def range_of_line offset=0; charmap = [] each_line do |line| charmap << (offset..(offset + line.length - 1)) offset += line.length end charmap end |
#rewrite(rules) ⇒ Object
Apply a set of rules in the form of regular expression matches to the string.
-
rules - The array containing rule-pairs (match, write).
Keep in mind that the order of rules is significant.
Returns the rewritten String.
CREDIT: George Moschovitis
14 15 16 17 18 19 20 21 |
# File 'lib/core/facets/string/rewrite.rb', line 14 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 |
#roman ⇒ Object
Considers string a Roman numeral numeral, and converts it to the corresponding integer.
NOTE: This is not (presently) a common core extension and is not loaded automatically when using require 'facets'.
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/core-uncommon/facets/integer/roman.rb', line 54 def roman roman = upcase raise unless roman? last = roman[-1,1] roman.reverse.split('').inject(0) do |result, c| if ROMAN_VALUES[c] < ROMAN_VALUES[last] result -= ROMAN_VALUES[c] else last = c result += ROMAN_VALUES[c] end end end |
#roman? ⇒ Boolean
Returns true iif the subject is a valid Roman numeral.
NOTE: This is not (presently) a common core extension and is not loaded automatically when using require 'facets'.
72 73 74 |
# File 'lib/core-uncommon/facets/integer/roman.rb', line 72 def roman? ROMAN =~ upcase end |
#shatter(re) ⇒ Object
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
15 16 17 18 19 20 |
# 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 |
#similarity(str_in) ⇒ Object
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".similarity("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.
Still a bit rough. Any suggestions for improvement are welcome.
CREDIT: Derek Lewis.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/core/facets/string/similarity.rb', line 28 def similarity(str_in) return 0 if str_in == nil return 1 if self == str_in # -- make a graph of each word (okay, 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{ |aa| matches.push(aa) if( graph_B.include?(aa) ) } #++ # -- 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( Regexp.escape(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 |
#snakecase ⇒ Object
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"
12 13 14 15 16 17 18 |
# 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) ⇒ Object
String#slice is essentially the same as #store.
a = "HELLO"
a.splice(1, "X")
a #=> "HXLLO"
But it acts like #slice! when given a single argument.
a = "HELLO"
a.splice(1) #=> "E"
a #=> "HLLO"
CREDIT: Trans
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/core/facets/string/splice.rb', line 19 def splice(idx, sub=nil) if sub store(idx, sub) else case idx when Range slice!(idx) else slice!(idx,1) end end end |
#squish ⇒ Object
Returns the string, first removing all whitespace on both ends of the string, and then changing remaining consecutive whitespace groups into one space each.
%{ Multi-line
string }.squish # => "Multi-line string"
" foo bar \n \t boo".squish # => "foo bar boo"
11 12 13 |
# File 'lib/core/facets/string/squish.rb', line 11 def squish dup.squish! end |
#squish! ⇒ Object
Performs a destructive squish. See String#squish.
16 17 18 19 20 |
# File 'lib/core/facets/string/squish.rb', line 16 def squish! strip! gsub!(/\s+/, ' ') self end |
#start_with?(prefix) ⇒ Boolean Also known as: starts_with?
Does a string start with the given prefix?
"hello".start_with?("he") #=> true
"hello".start_with?("to") #=> false
Note: This definition is better than standard Ruby’s becuase it handles regular expressions.
CREDIT: Juris Galang
30 31 32 33 |
# File 'lib/core/facets/string/start_with.rb', line 30 def start_with?(prefix) prefix = Regexp.escape(prefix.to_s) unless Regexp===prefix /^#{prefix}/.match(self) ? true : false end |
#tab(n) ⇒ Object
Aligns each line n spaces.
CREDIT: Gavin Sinclair
9 10 11 |
# File 'lib/core/facets/string/tab.rb', line 9 def tab(n) gsub(/^ */, ' ' * n) end |
#tabto(n) ⇒ Object
Preserves relative tabbing. The first non-empty line ends up with n spaces before nonspace.
CREDIT: Gavin Sinclair
10 11 12 13 14 15 16 |
# File 'lib/core/facets/string/tabto.rb', line 10 def tabto(n) if self =~ /^( *)\S/ indent(n - $1.length) else self end end |
#titlecase ⇒ Object
Title case.
"this is a string".titlecase
#=> "This Is A String"
CREDIT: Eliazar Parra
10 11 12 |
# File 'lib/core/facets/string/titlecase.rb', line 10 def titlecase gsub(/\b\w/){ $`[-1,1] == "'" ? $& : $&.upcase } end |
#to_b ⇒ Object
Interpret common affirmative string meanings as true, otherwise nil or false. Blank space and case are ignored. The following strings that will return true …
true
yes
on
t
1
y
==
The following strings will return nil …
nil
null
All other strings return false.
Here are some exmamples.
"true".to_b #=> true
"yes".to_b #=> true
"no".to_b #=> false
"123".to_b #=> false
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/core/facets/boolean.rb', line 96 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 ⇒ Object
Parse data from string.
427 428 429 430 |
# File 'lib/standard/facets/date.rb', line 427 def to_date #::Date::civil(*ParseDate.parsedate(self)[0..2]) ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday)) end |
#to_datetime ⇒ Object
Convert string to DateTime.
421 422 423 424 |
# File 'lib/standard/facets/date.rb', line 421 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) ⇒ Object
Turns a string into a regular expression.
"a?".to_re #=> /a?/
CREDIT: Trans
9 10 11 |
# 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) ⇒ Object
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
21 22 23 |
# 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) ⇒ Object
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.
266 267 268 |
# File 'lib/supplemental/facets/tuple.rb', line 266 def to_t( &yld ) Tuple.cast_from_string( self, &yld ) end |
#to_time(form = :utc) ⇒ Object
416 417 418 |
# File 'lib/standard/facets/date.rb', line 416 def to_time(form = :utc) ::Time.__send__("#{form}_time", *::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec).map{|arg| arg || 0 }) end |
#unbracket(bra = nil, ket = nil) ⇒ Object
Return a new string with the given brackets removed. If only one bracket char is given it will be removed from either side.
"{unwrap me}".unbracket('{') #=> "unwrap me"
"--unwrap me!".unbracket('--','!') #=> "unwrap me"
CREDIT: Trans
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# 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) ⇒ Object
Inplace version of #unbracket.
CREDIT: Trans
57 58 59 |
# File 'lib/core/facets/string/bracket.rb', line 57 def unbracket!(bra=nil, ket=nil) self.replace( unbracket(bra, ket) ) end |
#underscore ⇒ Object
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"
13 14 15 16 17 18 19 |
# File 'lib/core/facets/string/underscore.rb', line 13 def underscore gsub(/::/, '/'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). tr("-", "_"). downcase end |
#unfold ⇒ Object
Unfold paragrpahs.
FIXME: Sometimes adds one too many blank lines. TEST!!!
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 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 |
#unindent(size = nil) ⇒ Object
Remove excessive indentation. Useful for multi-line strings embeded in already indented code.
<<-END.unindent
ohaie
wurld
END
Outputs …
ohaie
wurld
Instead of …
ohaie
wurld
CREDIT: Noah Gibbs, mynyml
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/core/facets/string/indent.rb', line 42 def unindent(size=nil) if size indent(-size) else char = ' ' self.scan(/^[\ \t]*\S/) do |m| if size.nil? || m.size < size size = m.size char = m[0...-1] end end size -= 1 indent(-size, char) end end |
#unindent! ⇒ Object
Equivalent to String#unindent, but modifies the receiver in place.
CREDIT: mynyml
62 63 64 |
# File 'lib/core/facets/string/indent.rb', line 62 def unindent! self.replace(self.unindent) end |
#unquote ⇒ Object
Remove quotes from string.
"'hi'".unquote #=> "hi"
CREDIT: Trans
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/core/facets/string/quote.rb', line 76 def unquote s = self.dup case self[0,1] when "'", '"', '`' s[0] = '' end case self[-1,1] when "'", '"', '`' s[-1] = '' end return s end |
#upcase? ⇒ Boolean
Is the string upcase/uppercase?
"THIS".upcase? #=> true
"This".upcase? #=> false
"this".upcase? #=> false
CREDIT: Phil Tomson
41 42 43 |
# File 'lib/core/facets/string/capitalized.rb', line 41 def upcase? upcase == self end |
#upper_camelcase ⇒ Object
46 47 48 49 50 51 |
# File 'lib/core/facets/string/camelcase.rb', line 46 def upper_camelcase #str = dup #str.gsub!(/\/(.?)/){ "::#{$1.upcase}" } # NOT SO SURE ABOUT THIS #str.gsub!(/(?:_+|-+)([a-z])/){ $1.upcase } inter_camelcase.gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase } end |
#uppercase ⇒ Object
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.
10 11 12 13 |
# File 'lib/core/facets/string/uppercase.rb', line 10 def uppercase str = to_s str[0,1].upcase + str[1..-1] end |
#variablize ⇒ Object
Prepend an “@” to the beginning of a string to make a instance variable name. This also replaces non-valid characters with underscores.
7 8 9 10 |
# File 'lib/core/facets/string/variablize.rb', line 7 def variablize v = gsub(/\W/, '_') "@#{v}" end |
#word_wrap(col_width = 80) ⇒ Object
Word wrap a string not exceeding max width.
"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
18 19 20 |
# 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) ⇒ Object
As with #word_wrap, but modifies the string in place.
CREDIT: Gavin Kistner, Dayne Broderson
26 27 28 29 30 |
# 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 ⇒ Object
Returns an array of characters.
"abc 123".words #=> ["abc","123"]
7 8 9 |
# File 'lib/core/facets/string/words.rb', line 7 def words self.split(/\s+/) end |