Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/AnonR/anonr.TX.../opt/alt/ruby18/lib64/ruby/1.8
File: scanf.rb
# scanf for Ruby
[0] Fix | Delete
#
[1] Fix | Delete
# $Revision: 21682 $
[2] Fix | Delete
# $Id: scanf.rb 21682 2009-01-20 03:23:46Z shyouhei $
[3] Fix | Delete
# $Author: shyouhei $
[4] Fix | Delete
# $Date: 2009-01-20 12:23:46 +0900 (Tue, 20 Jan 2009) $
[5] Fix | Delete
#
[6] Fix | Delete
# A product of the Austin Ruby Codefest (Austin, Texas, August 2002)
[7] Fix | Delete
[8] Fix | Delete
=begin
[9] Fix | Delete
[10] Fix | Delete
=scanf for Ruby
[11] Fix | Delete
[12] Fix | Delete
==Description
[13] Fix | Delete
[14] Fix | Delete
scanf for Ruby is an implementation of the C function scanf(3),
[15] Fix | Delete
modified as necessary for Ruby compatibility.
[16] Fix | Delete
[17] Fix | Delete
The methods provided are String#scanf, IO#scanf, and
[18] Fix | Delete
Kernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf. IO#scanf
[19] Fix | Delete
can be used on any IO stream, including file handles and sockets.
[20] Fix | Delete
scanf can be called either with or without a block.
[21] Fix | Delete
[22] Fix | Delete
scanf for Ruby scans an input string or stream according to a
[23] Fix | Delete
<b>format</b>, as described below ("Conversions"), and returns an
[24] Fix | Delete
array of matches between the format and the input. The format is
[25] Fix | Delete
defined in a string, and is similar (though not identical) to the
[26] Fix | Delete
formats used in Kernel#printf and Kernel#sprintf.
[27] Fix | Delete
[28] Fix | Delete
The format may contain <b>conversion specifiers</b>, which tell scanf
[29] Fix | Delete
what form (type) each particular matched substring should be converted
[30] Fix | Delete
to (e.g., decimal integer, floating point number, literal string,
[31] Fix | Delete
etc.) The matches and conversions take place from left to right, and
[32] Fix | Delete
the conversions themselves are returned as an array.
[33] Fix | Delete
[34] Fix | Delete
The format string may also contain characters other than those in the
[35] Fix | Delete
conversion specifiers. White space (blanks, tabs, or newlines) in the
[36] Fix | Delete
format string matches any amount of white space, including none, in
[37] Fix | Delete
the input. Everything else matches only itself.
[38] Fix | Delete
[39] Fix | Delete
Scanning stops, and scanf returns, when any input character fails to
[40] Fix | Delete
match the specifications in the format string, or when input is
[41] Fix | Delete
exhausted, or when everything in the format string has been
[42] Fix | Delete
matched. All matches found up to the stopping point are returned in
[43] Fix | Delete
the return array (or yielded to the block, if a block was given).
[44] Fix | Delete
[45] Fix | Delete
[46] Fix | Delete
==Basic usage
[47] Fix | Delete
[48] Fix | Delete
require 'scanf.rb'
[49] Fix | Delete
[50] Fix | Delete
# String#scanf and IO#scanf take a single argument (a format string)
[51] Fix | Delete
array = aString.scanf("%d%s")
[52] Fix | Delete
array = anIO.scanf("%d%s")
[53] Fix | Delete
[54] Fix | Delete
# Kernel#scanf reads from STDIN
[55] Fix | Delete
array = scanf("%d%s")
[56] Fix | Delete
[57] Fix | Delete
==Block usage
[58] Fix | Delete
[59] Fix | Delete
When called with a block, scanf keeps scanning the input, cycling back
[60] Fix | Delete
to the beginning of the format string, and yields a new array of
[61] Fix | Delete
conversions to the block every time the format string is matched
[62] Fix | Delete
(including partial matches, but not including complete failures). The
[63] Fix | Delete
actual return value of scanf when called with a block is an array
[64] Fix | Delete
containing the results of all the executions of the block.
[65] Fix | Delete
[66] Fix | Delete
str = "123 abc 456 def 789 ghi"
[67] Fix | Delete
str.scanf("%d%s") { |num,str| [ num * 2, str.upcase ] }
[68] Fix | Delete
# => [[246, "ABC"], [912, "DEF"], [1578, "GHI"]]
[69] Fix | Delete
[70] Fix | Delete
==Conversions
[71] Fix | Delete
[72] Fix | Delete
The single argument to scanf is a format string, which generally
[73] Fix | Delete
includes one or more conversion specifiers. Conversion specifiers
[74] Fix | Delete
begin with the percent character ('%') and include information about
[75] Fix | Delete
what scanf should next scan for (string, decimal number, single
[76] Fix | Delete
character, etc.).
[77] Fix | Delete
[78] Fix | Delete
There may be an optional maximum field width, expressed as a decimal
[79] Fix | Delete
integer, between the % and the conversion. If no width is given, a
[80] Fix | Delete
default of `infinity' is used (with the exception of the %c specifier;
[81] Fix | Delete
see below). Otherwise, given a field width of <em>n</em> for a given
[82] Fix | Delete
conversion, at most <em>n</em> characters are scanned in processing
[83] Fix | Delete
that conversion. Before conversion begins, most conversions skip
[84] Fix | Delete
white space in the input string; this white space is not counted
[85] Fix | Delete
against the field width.
[86] Fix | Delete
[87] Fix | Delete
The following conversions are available. (See the files EXAMPLES
[88] Fix | Delete
and <tt>tests/scanftests.rb</tt> for examples.)
[89] Fix | Delete
[90] Fix | Delete
[%]
[91] Fix | Delete
Matches a literal `%'. That is, `%%' in the format string matches a
[92] Fix | Delete
single input `%' character. No conversion is done, and the resulting
[93] Fix | Delete
'%' is not included in the return array.
[94] Fix | Delete
[95] Fix | Delete
[d]
[96] Fix | Delete
Matches an optionally signed decimal integer.
[97] Fix | Delete
[98] Fix | Delete
[u]
[99] Fix | Delete
Same as d.
[100] Fix | Delete
[101] Fix | Delete
[i]
[102] Fix | Delete
Matches an optionally signed integer. The integer is read in base
[103] Fix | Delete
16 if it begins with `0x' or `0X', in base 8 if it begins with `0',
[104] Fix | Delete
and in base 10 other- wise. Only characters that correspond to the
[105] Fix | Delete
base are recognized.
[106] Fix | Delete
[107] Fix | Delete
[o]
[108] Fix | Delete
Matches an optionally signed octal integer.
[109] Fix | Delete
[110] Fix | Delete
[x,X]
[111] Fix | Delete
Matches an optionally signed hexadecimal integer,
[112] Fix | Delete
[113] Fix | Delete
[f,g,e,E]
[114] Fix | Delete
Matches an optionally signed floating-point number.
[115] Fix | Delete
[116] Fix | Delete
[s]
[117] Fix | Delete
Matches a sequence of non-white-space character. The input string stops at
[118] Fix | Delete
white space or at the maximum field width, whichever occurs first.
[119] Fix | Delete
[120] Fix | Delete
[c]
[121] Fix | Delete
Matches a single character, or a sequence of <em>n</em> characters if a
[122] Fix | Delete
field width of <em>n</em> is specified. The usual skip of leading white
[123] Fix | Delete
space is suppressed. To skip white space first, use an explicit space in
[124] Fix | Delete
the format.
[125] Fix | Delete
[126] Fix | Delete
[<tt>[</tt>]
[127] Fix | Delete
Matches a nonempty sequence of characters from the specified set
[128] Fix | Delete
of accepted characters. The usual skip of leading white space is
[129] Fix | Delete
suppressed. This bracketed sub-expression is interpreted exactly like a
[130] Fix | Delete
character class in a Ruby regular expression. (In fact, it is placed as-is
[131] Fix | Delete
in a regular expression.) The matching against the input string ends with
[132] Fix | Delete
the appearance of a character not in (or, with a circumflex, in) the set,
[133] Fix | Delete
or when the field width runs out, whichever comes first.
[134] Fix | Delete
[135] Fix | Delete
===Assignment suppression
[136] Fix | Delete
[137] Fix | Delete
To require that a particular match occur, but without including the result
[138] Fix | Delete
in the return array, place the <b>assignment suppression flag</b>, which is
[139] Fix | Delete
the star character ('*'), immediately after the leading '%' of a format
[140] Fix | Delete
specifier (just before the field width, if any).
[141] Fix | Delete
[142] Fix | Delete
==Examples
[143] Fix | Delete
[144] Fix | Delete
See the files <tt>EXAMPLES</tt> and <tt>tests/scanftests.rb</tt>.
[145] Fix | Delete
[146] Fix | Delete
==scanf for Ruby compared with scanf in C
[147] Fix | Delete
[148] Fix | Delete
scanf for Ruby is based on the C function scanf(3), but with modifications,
[149] Fix | Delete
dictated mainly by the underlying differences between the languages.
[150] Fix | Delete
[151] Fix | Delete
===Unimplemented flags and specifiers
[152] Fix | Delete
[153] Fix | Delete
* The only flag implemented in scanf for Ruby is '<tt>*</tt>' (ignore
[154] Fix | Delete
upcoming conversion). Many of the flags available in C versions of scanf(4)
[155] Fix | Delete
have to do with the type of upcoming pointer arguments, and are literally
[156] Fix | Delete
meaningless in Ruby.
[157] Fix | Delete
[158] Fix | Delete
* The <tt>n</tt> specifier (store number of characters consumed so far in
[159] Fix | Delete
next pointer) is not implemented.
[160] Fix | Delete
[161] Fix | Delete
* The <tt>p</tt> specifier (match a pointer value) is not implemented.
[162] Fix | Delete
[163] Fix | Delete
===Altered specifiers
[164] Fix | Delete
[165] Fix | Delete
[o,u,x,X]
[166] Fix | Delete
In scanf for Ruby, all of these specifiers scan for an optionally signed
[167] Fix | Delete
integer, rather than for an unsigned integer like their C counterparts.
[168] Fix | Delete
[169] Fix | Delete
===Return values
[170] Fix | Delete
[171] Fix | Delete
scanf for Ruby returns an array of successful conversions, whereas
[172] Fix | Delete
scanf(3) returns the number of conversions successfully
[173] Fix | Delete
completed. (See below for more details on scanf for Ruby's return
[174] Fix | Delete
values.)
[175] Fix | Delete
[176] Fix | Delete
==Return values
[177] Fix | Delete
[178] Fix | Delete
Without a block, scanf returns an array containing all the conversions
[179] Fix | Delete
it has found. If none are found, scanf will return an empty array. An
[180] Fix | Delete
unsuccesful match is never ignored, but rather always signals the end
[181] Fix | Delete
of the scanning operation. If the first unsuccessful match takes place
[182] Fix | Delete
after one or more successful matches have already taken place, the
[183] Fix | Delete
returned array will contain the results of those successful matches.
[184] Fix | Delete
[185] Fix | Delete
With a block scanf returns a 'map'-like array of transformations from
[186] Fix | Delete
the block -- that is, an array reflecting what the block did with each
[187] Fix | Delete
yielded result from the iterative scanf operation. (See "Block
[188] Fix | Delete
usage", above.)
[189] Fix | Delete
[190] Fix | Delete
==Test suite
[191] Fix | Delete
[192] Fix | Delete
scanf for Ruby includes a suite of unit tests (requiring the
[193] Fix | Delete
<tt>TestUnit</tt> package), which can be run with the command <tt>ruby
[194] Fix | Delete
tests/scanftests.rb</tt> or the command <tt>make test</tt>.
[195] Fix | Delete
[196] Fix | Delete
==Current limitations and bugs
[197] Fix | Delete
[198] Fix | Delete
When using IO#scanf under Windows, make sure you open your files in
[199] Fix | Delete
binary mode:
[200] Fix | Delete
[201] Fix | Delete
File.open("filename", "rb")
[202] Fix | Delete
[203] Fix | Delete
so that scanf can keep track of characters correctly.
[204] Fix | Delete
[205] Fix | Delete
Support for character classes is reasonably complete (since it
[206] Fix | Delete
essentially piggy-backs on Ruby's regular expression handling of
[207] Fix | Delete
character classes), but users are advised that character class testing
[208] Fix | Delete
has not been exhaustive, and that they should exercise some caution
[209] Fix | Delete
in using any of the more complex and/or arcane character class
[210] Fix | Delete
idioms.
[211] Fix | Delete
[212] Fix | Delete
[213] Fix | Delete
==Technical notes
[214] Fix | Delete
[215] Fix | Delete
===Rationale behind scanf for Ruby
[216] Fix | Delete
[217] Fix | Delete
The impetus for a scanf implementation in Ruby comes chiefly from the fact
[218] Fix | Delete
that existing pattern matching operations, such as Regexp#match and
[219] Fix | Delete
String#scan, return all results as strings, which have to be converted to
[220] Fix | Delete
integers or floats explicitly in cases where what's ultimately wanted are
[221] Fix | Delete
integer or float values.
[222] Fix | Delete
[223] Fix | Delete
===Design of scanf for Ruby
[224] Fix | Delete
[225] Fix | Delete
scanf for Ruby is essentially a <format string>-to-<regular
[226] Fix | Delete
expression> converter.
[227] Fix | Delete
[228] Fix | Delete
When scanf is called, a FormatString object is generated from the
[229] Fix | Delete
format string ("%d%s...") argument. The FormatString object breaks the
[230] Fix | Delete
format string down into atoms ("%d", "%5f", "blah", etc.), and from
[231] Fix | Delete
each atom it creates a FormatSpecifier object, which it
[232] Fix | Delete
saves.
[233] Fix | Delete
[234] Fix | Delete
Each FormatSpecifier has a regular expression fragment and a "handler"
[235] Fix | Delete
associated with it. For example, the regular expression fragment
[236] Fix | Delete
associated with the format "%d" is "([-+]?\d+)", and the handler
[237] Fix | Delete
associated with it is a wrapper around String#to_i. scanf itself calls
[238] Fix | Delete
FormatString#match, passing in the input string. FormatString#match
[239] Fix | Delete
iterates through its FormatSpecifiers; for each one, it matches the
[240] Fix | Delete
corresponding regular expression fragment against the string. If
[241] Fix | Delete
there's a match, it sends the matched string to the handler associated
[242] Fix | Delete
with the FormatSpecifier.
[243] Fix | Delete
[244] Fix | Delete
Thus, to follow up the "%d" example: if "123" occurs in the input
[245] Fix | Delete
string when a FormatSpecifier consisting of "%d" is reached, the "123"
[246] Fix | Delete
will be matched against "([-+]?\d+)", and the matched string will be
[247] Fix | Delete
rendered into an integer by a call to to_i.
[248] Fix | Delete
[249] Fix | Delete
The rendered match is then saved to an accumulator array, and the
[250] Fix | Delete
input string is reduced to the post-match substring. Thus the string
[251] Fix | Delete
is "eaten" from the left as the FormatSpecifiers are applied in
[252] Fix | Delete
sequence. (This is done to a duplicate string; the original string is
[253] Fix | Delete
not altered.)
[254] Fix | Delete
[255] Fix | Delete
As soon as a regular expression fragment fails to match the string, or
[256] Fix | Delete
when the FormatString object runs out of FormatSpecifiers, scanning
[257] Fix | Delete
stops and results accumulated so far are returned in an array.
[258] Fix | Delete
[259] Fix | Delete
==License and copyright
[260] Fix | Delete
[261] Fix | Delete
Copyright:: (c) 2002-2003 David Alan Black
[262] Fix | Delete
License:: Distributed on the same licensing terms as Ruby itself
[263] Fix | Delete
[264] Fix | Delete
==Warranty disclaimer
[265] Fix | Delete
[266] Fix | Delete
This software is provided "as is" and without any express or implied
[267] Fix | Delete
warranties, including, without limitation, the implied warranties of
[268] Fix | Delete
merchantibility and fitness for a particular purpose.
[269] Fix | Delete
[270] Fix | Delete
==Credits and acknowledgements
[271] Fix | Delete
[272] Fix | Delete
scanf for Ruby was developed as the major activity of the Austin
[273] Fix | Delete
Ruby Codefest (Austin, Texas, August 2002).
[274] Fix | Delete
[275] Fix | Delete
Principal author:: David Alan Black (mailto:dblack@superlink.net)
[276] Fix | Delete
Co-author:: Hal Fulton (mailto:hal9000@hypermetrics.com)
[277] Fix | Delete
Project contributors:: Nolan Darilek, Jason Johnston
[278] Fix | Delete
[279] Fix | Delete
Thanks to Hal Fulton for hosting the Codefest.
[280] Fix | Delete
[281] Fix | Delete
Thanks to Matz for suggestions about the class design.
[282] Fix | Delete
[283] Fix | Delete
Thanks to Gavin Sinclair for some feedback on the documentation.
[284] Fix | Delete
[285] Fix | Delete
The text for parts of this document, especially the Description and
[286] Fix | Delete
Conversions sections, above, were adapted from the Linux Programmer's
[287] Fix | Delete
Manual manpage for scanf(3), dated 1995-11-01.
[288] Fix | Delete
[289] Fix | Delete
==Bugs and bug reports
[290] Fix | Delete
[291] Fix | Delete
scanf for Ruby is based on something of an amalgam of C scanf
[292] Fix | Delete
implementations and documentation, rather than on a single canonical
[293] Fix | Delete
description. Suggestions for features and behaviors which appear in
[294] Fix | Delete
other scanfs, and would be meaningful in Ruby, are welcome, as are
[295] Fix | Delete
reports of suspicious behaviors and/or bugs. (Please see "Credits and
[296] Fix | Delete
acknowledgements", above, for email addresses.)
[297] Fix | Delete
[298] Fix | Delete
=end
[299] Fix | Delete
[300] Fix | Delete
module Scanf
[301] Fix | Delete
[302] Fix | Delete
class FormatSpecifier
[303] Fix | Delete
[304] Fix | Delete
attr_reader :re_string, :matched_string, :conversion, :matched
[305] Fix | Delete
[306] Fix | Delete
private
[307] Fix | Delete
[308] Fix | Delete
def skip; /^\s*%\*/.match(@spec_string); end
[309] Fix | Delete
[310] Fix | Delete
def extract_float(s); s.to_f if s &&! skip; end
[311] Fix | Delete
def extract_decimal(s); s.to_i if s &&! skip; end
[312] Fix | Delete
def extract_hex(s); s.hex if s &&! skip; end
[313] Fix | Delete
def extract_octal(s); s.oct if s &&! skip; end
[314] Fix | Delete
def extract_integer(s); Integer(s) if s &&! skip; end
[315] Fix | Delete
def extract_plain(s); s unless skip; end
[316] Fix | Delete
[317] Fix | Delete
def nil_proc(s); nil; end
[318] Fix | Delete
[319] Fix | Delete
public
[320] Fix | Delete
[321] Fix | Delete
def to_s
[322] Fix | Delete
@spec_string
[323] Fix | Delete
end
[324] Fix | Delete
[325] Fix | Delete
def count_space?
[326] Fix | Delete
/(?:\A|\S)%\*?\d*c|\[/.match(@spec_string)
[327] Fix | Delete
end
[328] Fix | Delete
[329] Fix | Delete
def initialize(str)
[330] Fix | Delete
@spec_string = str
[331] Fix | Delete
h = '[A-Fa-f0-9]'
[332] Fix | Delete
[333] Fix | Delete
@re_string, @handler =
[334] Fix | Delete
case @spec_string
[335] Fix | Delete
[336] Fix | Delete
# %[[:...:]]
[337] Fix | Delete
when /%\*?(\[\[:[a-z]+:\]\])/
[338] Fix | Delete
[ "(#{$1}+)", :extract_plain ]
[339] Fix | Delete
[340] Fix | Delete
# %5[[:...:]]
[341] Fix | Delete
when /%\*?(\d+)(\[\[:[a-z]+:\]\])/
[342] Fix | Delete
[ "(#{$2}{1,#{$1}})", :extract_plain ]
[343] Fix | Delete
[344] Fix | Delete
# %[...]
[345] Fix | Delete
when /%\*?\[([^\]]*)\]/
[346] Fix | Delete
yes = $1
[347] Fix | Delete
if /^\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end
[348] Fix | Delete
[ "([#{yes}]+)(?=[#{no}]|\\z)", :extract_plain ]
[349] Fix | Delete
[350] Fix | Delete
# %5[...]
[351] Fix | Delete
when /%\*?(\d+)\[([^\]]*)\]/
[352] Fix | Delete
yes = $2
[353] Fix | Delete
w = $1
[354] Fix | Delete
[ "([#{yes}]{1,#{w}})", :extract_plain ]
[355] Fix | Delete
[356] Fix | Delete
# %i
[357] Fix | Delete
when /%\*?i/
[358] Fix | Delete
[ "([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\d*)))", :extract_integer ]
[359] Fix | Delete
[360] Fix | Delete
# %5i
[361] Fix | Delete
when /%\*?(\d+)i/
[362] Fix | Delete
n = $1.to_i
[363] Fix | Delete
s = "("
[364] Fix | Delete
if n > 1 then s += "[1-9]\\d{1,#{n-1}}|" end
[365] Fix | Delete
if n > 1 then s += "0[0-7]{1,#{n-1}}|" end
[366] Fix | Delete
if n > 2 then s += "[-+]0[0-7]{1,#{n-2}}|" end
[367] Fix | Delete
if n > 2 then s += "[-+][1-9]\\d{1,#{n-2}}|" end
[368] Fix | Delete
if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
[369] Fix | Delete
if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
[370] Fix | Delete
s += "\\d"
[371] Fix | Delete
s += ")"
[372] Fix | Delete
[ s, :extract_integer ]
[373] Fix | Delete
[374] Fix | Delete
# %d, %u
[375] Fix | Delete
when /%\*?[du]/
[376] Fix | Delete
[ '([-+]?\d+)', :extract_decimal ]
[377] Fix | Delete
[378] Fix | Delete
# %5d, %5u
[379] Fix | Delete
when /%\*?(\d+)[du]/
[380] Fix | Delete
n = $1.to_i
[381] Fix | Delete
s = "("
[382] Fix | Delete
if n > 1 then s += "[-+]\\d{1,#{n-1}}|" end
[383] Fix | Delete
s += "\\d{1,#{$1}})"
[384] Fix | Delete
[ s, :extract_decimal ]
[385] Fix | Delete
[386] Fix | Delete
# %x
[387] Fix | Delete
when /%\*?[Xx]/
[388] Fix | Delete
[ "([-+]?(?:0[Xx])?#{h}+)", :extract_hex ]
[389] Fix | Delete
[390] Fix | Delete
# %5x
[391] Fix | Delete
when /%\*?(\d+)[Xx]/
[392] Fix | Delete
n = $1.to_i
[393] Fix | Delete
s = "("
[394] Fix | Delete
if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
[395] Fix | Delete
if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
[396] Fix | Delete
if n > 1 then s += "[-+]#{h}{1,#{n-1}}|" end
[397] Fix | Delete
s += "#{h}{1,#{n}}"
[398] Fix | Delete
s += ")"
[399] Fix | Delete
[ s, :extract_hex ]
[400] Fix | Delete
[401] Fix | Delete
# %o
[402] Fix | Delete
when /%\*?o/
[403] Fix | Delete
[ '([-+]?[0-7]+)', :extract_octal ]
[404] Fix | Delete
[405] Fix | Delete
# %5o
[406] Fix | Delete
when /%\*?(\d+)o/
[407] Fix | Delete
[ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ]
[408] Fix | Delete
[409] Fix | Delete
# %f
[410] Fix | Delete
when /%\*?f/
[411] Fix | Delete
[ '([-+]?((\d+(?>(?=[^\d.]|$)))|(\d*(\.(\d*([eE][-+]?\d+)?)))))', :extract_float ]
[412] Fix | Delete
[413] Fix | Delete
# %5f
[414] Fix | Delete
when /%\*?(\d+)f/
[415] Fix | Delete
[ "(\\S{1,#{$1}})", :extract_float ]
[416] Fix | Delete
[417] Fix | Delete
# %5s
[418] Fix | Delete
when /%\*?(\d+)s/
[419] Fix | Delete
[ "(\\S{1,#{$1}})", :extract_plain ]
[420] Fix | Delete
[421] Fix | Delete
# %s
[422] Fix | Delete
when /%\*?s/
[423] Fix | Delete
[ '(\S+)', :extract_plain ]
[424] Fix | Delete
[425] Fix | Delete
# %c
[426] Fix | Delete
when /\s%\*?c/
[427] Fix | Delete
[ "\\s*(.)", :extract_plain ]
[428] Fix | Delete
[429] Fix | Delete
# %c
[430] Fix | Delete
when /%\*?c/
[431] Fix | Delete
[ "(.)", :extract_plain ]
[432] Fix | Delete
[433] Fix | Delete
# %5c (whitespace issues are handled by the count_*_space? methods)
[434] Fix | Delete
when /%\*?(\d+)c/
[435] Fix | Delete
[ "(.{1,#{$1}})", :extract_plain ]
[436] Fix | Delete
[437] Fix | Delete
# %%
[438] Fix | Delete
when /%%/
[439] Fix | Delete
[ '(\s*%)', :nil_proc ]
[440] Fix | Delete
[441] Fix | Delete
# literal characters
[442] Fix | Delete
else
[443] Fix | Delete
[ "(#{Regexp.escape(@spec_string)})", :nil_proc ]
[444] Fix | Delete
end
[445] Fix | Delete
[446] Fix | Delete
@re_string = '\A' + @re_string
[447] Fix | Delete
end
[448] Fix | Delete
[449] Fix | Delete
def to_re
[450] Fix | Delete
Regexp.new(@re_string,Regexp::MULTILINE)
[451] Fix | Delete
end
[452] Fix | Delete
[453] Fix | Delete
def match(str)
[454] Fix | Delete
@matched = false
[455] Fix | Delete
s = str.dup
[456] Fix | Delete
s.sub!(/\A\s+/,'') unless count_space?
[457] Fix | Delete
res = to_re.match(s)
[458] Fix | Delete
if res
[459] Fix | Delete
@conversion = send(@handler, res[1])
[460] Fix | Delete
@matched_string = @conversion.to_s
[461] Fix | Delete
@matched = true
[462] Fix | Delete
end
[463] Fix | Delete
res
[464] Fix | Delete
end
[465] Fix | Delete
[466] Fix | Delete
def letter
[467] Fix | Delete
/%\*?\d*([a-z\[])/.match(@spec_string).to_a[1]
[468] Fix | Delete
end
[469] Fix | Delete
[470] Fix | Delete
def width
[471] Fix | Delete
w = /%\*?(\d+)/.match(@spec_string).to_a[1]
[472] Fix | Delete
w && w.to_i
[473] Fix | Delete
end
[474] Fix | Delete
[475] Fix | Delete
def mid_match?
[476] Fix | Delete
return false unless @matched
[477] Fix | Delete
cc_no_width = letter == '[' &&! width
[478] Fix | Delete
c_or_cc_width = (letter == 'c' || letter == '[') && width
[479] Fix | Delete
width_left = c_or_cc_width && (matched_string.size < width)
[480] Fix | Delete
[481] Fix | Delete
return width_left || cc_no_width
[482] Fix | Delete
end
[483] Fix | Delete
[484] Fix | Delete
end
[485] Fix | Delete
[486] Fix | Delete
class FormatString
[487] Fix | Delete
[488] Fix | Delete
attr_reader :string_left, :last_spec_tried,
[489] Fix | Delete
:last_match_tried, :matched_count, :space
[490] Fix | Delete
[491] Fix | Delete
SPECIFIERS = 'diuXxofeEgsc'
[492] Fix | Delete
REGEX = /
[493] Fix | Delete
# possible space, followed by...
[494] Fix | Delete
(?:\s*
[495] Fix | Delete
# percent sign, followed by...
[496] Fix | Delete
%
[497] Fix | Delete
# another percent sign, or...
[498] Fix | Delete
(?:%|
[499] Fix | Delete
12
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function