This is an extension to Ruby's String class. Just put this code in a file and include it. This basically takes a string and adds literals and padding to it. For example, you can format a phone number like this:
1
2 "5445556747".using('(###) ###-####', '', true)
3 => (544) 555-6747
1
2 require 'strscan'
3
4 class String
5
6
7
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 def using(pattern, fill='', right=false, fixchar='#', remchar='&')
52
53 remCount = pattern.count(remchar)
54 raise ArgumentError.new("Too many #{remchar}") if remCount > 1
55 raise ArgumentError.new("#{fixchar} too long") if fixchar.length > 1
56 raise ArgumentError.new("#{remchar} too long") if remchar.length > 1
57 raise ArgumentError.new("#{fill} too long") if fill.length > 1
58 remaining = remCount != 0
59 slots = pattern.count(fixchar)
60
61
62 if fill.nil?
63 return self if self.length < slots
64 return self if self.length > slots and !remaining
65 end
66
67
68 source = if fill.nil? || fill.empty? then
69 self
70 elsif right then
71 self.rjust(slots, fill)
72 else
73 self.ljust(slots, fill)
74 end
75
76
77 if source.length > slots && !remaining then
78 source = right ? source[-source.length, source.length] :
79 source[0, source.length]
80 end
81
82
83 if !fill.nil? && fill.empty? then
84
85 if source.length < slots
86 keepCount = source.length
87 leftmost, rightmost = 0, pattern.length - 1
88 if right then
89
90
91 leftmost = (1...keepCount).inject(pattern.rindex(fixchar)) {
92 |leftmost, n| pattern.rindex(fixchar, leftmost - 1) }
93 else
94
95 rightmost = (1...keepCount).inject(pattern.index(fixchar)) {
96 |rightmost, n| pattern.index(fixchar, rightmost + 1) }
97 end
98 pattern = pattern[leftmost..rightmost]
99 slots = pattern.count(fixchar)
100 end
101
102
103
104 if source.length == slots then
105 if pattern.match("^#{Regexp.escape(remchar)}") then
106 pattern = pattern[pattern.index(fixchar) || 0 ... pattern.length]
107 elsif pattern.match("#{Regexp.escape(remchar)}$") then
108 pattern = pattern[0 ... (pattern.rindex(fixchar) + fixchar.length) || pattern.length]
109 end
110 end
111
112 end
113
114
115 remSize = source.length - slots
116 if remSize < 0 then remSize = 0; end
117
118
119 scanner = ::StringScanner.new(pattern)
120 sourceIndex = 0
121 result = ''
122 fixRegexp = Regexp.new(Regexp.escape(fixchar))
123 remRegexp = Regexp.new(Regexp.escape(remchar))
124 while not scanner.eos?
125 if scanner.scan(fixRegexp) then
126 result += source[sourceIndex].chr
127 sourceIndex += 1
128 elsif scanner.scan(remRegexp) then
129 result += source[sourceIndex, remSize]
130 sourceIndex += remSize
131 else
132 result += scanner.getch
133 end
134 end
135
136 result
137 end
138 end