Class: Axlsx::Worksheet
- Inherits:
-
Object
- Object
- Axlsx::Worksheet
- Defined in:
- lib/axlsx/workbook/worksheet/worksheet.rb
Overview
The Worksheet class represents a worksheet in the workbook.
Instance Attribute Summary collapse
-
#auto_filter ⇒ Object
An range that excel will apply an autfilter to “A1:B3” This will turn filtering on for the cells in the range.
-
#auto_fit_data ⇒ Array
readonly
An array of content based calculated column widths.
-
#column_info ⇒ SimpleTypedList
readonly
Column info for the sheet.
-
#comments ⇒ SimpleTypedList
readonly
The comments associated with this worksheet.
-
#merged_cells ⇒ Object
readonly
An array of merged cell ranges e.d “A1:B3” Content and formatting is read from the first cell.
-
#name ⇒ String
The name of the worksheet.
-
#protected_ranges ⇒ SimpleTypedList
readonly
A collection of protected ranges in the worksheet.
-
#rows ⇒ SimpleTypedList
readonly
The rows in this worksheet.
-
#tables ⇒ Array
readonly
The tables in this worksheet.
-
#workbook ⇒ Workbook
readonly
The workbook that owns this worksheet.
Class Method Summary collapse
-
.thin_chars ⇒ String
definition of characters which are less than the maximum width of 0-9 in the default font for use in String#count.
Instance Method Summary collapse
-
#[](cell_def) ⇒ Cell, Array
Returns the cell or cells defined using excel style A1:B3 references.
-
#abs_auto_filter ⇒ Object
The absolute auto filter range.
-
#add_chart(chart_type, options = {}) {|chart| ... } ⇒ Object
Adds a chart to this worksheets drawing.
-
#add_comment(options = {}) ⇒ Object
Shortcut to comments#add_comment.
-
#add_conditional_formatting(cells, rules) ⇒ Object
Add conditional formatting to this worksheet.
-
#add_data_validation(cells, data_validation) ⇒ Object
Add data validation to this worksheet.
-
#add_image(options = {}) {|image| ... } ⇒ Object
Adds a media item to the worksheets drawing.
-
#add_row(values = [], options = {}) {|@rows.last| ... } ⇒ Row
(also: #<<)
Adds a row to the worksheet and updates auto fit data.
-
#add_table(ref, options = {}) {|table| ... } ⇒ Object
needs documentation.
-
#cells ⇒ Array
convinience method to access all cells in this worksheet.
-
#col_style(index, style, options = {}) ⇒ Object
Set the style for cells in a specific column.
-
#cols ⇒ Object
returns the sheet data as columnw.
-
#column_widths(*widths) ⇒ Object
This is a helper method that Lets you specify a fixed width for multiple columns in a worksheet in one go.
-
#dimension ⇒ String
The demensions of a worksheet.
-
#drawing ⇒ Drawing
The drawing associated with this worksheet.
- #fit_to_page=(v) ⇒ Boolean
-
#fit_to_page? ⇒ Boolean
Indicates if the worksheet will be fit by witdh or height to a specific number of pages.
-
#index ⇒ Integer
The index of this worksheet in the owning Workbook’s worksheets list.
-
#initialize(wb, options = {}) ⇒ Worksheet
constructor
Creates a new worksheet.
-
#merge_cells(cells) ⇒ Object
Creates merge information for this worksheet.
-
#name_to_cell(name) ⇒ Cell
returns the column and row index for a named based cell.
-
#page_margins {|@page_margins| ... } ⇒ PageMargins
Page margins for printing the worksheet.
-
#page_setup {|@page_setup| ... } ⇒ PageSetup
Page setup settings for printing the worksheet.
-
#pn ⇒ String
The part name of this worksheet.
-
#print_options {|@print_options| ... } ⇒ PrintOptions
Options for printing the worksheet.
-
#protect_range(cells) ⇒ ProtectedRange
Adds a new protected cell range to the worksheet.
-
#relationships ⇒ Relationships
The worksheet relationships.
-
#rels_pn ⇒ String
The relationship part name of this worksheet.
-
#rId ⇒ String
The relationship Id of thiw worksheet.
-
#row_style(index, style, options = {}) ⇒ Object
Set the style for cells in a specific row.
-
#selected ⇒ Object
deprecated
Deprecated.
Use SheetView#tab_selected instead.
-
#selected=(v) ⇒ Boolean
deprecated
Deprecated.
Use SheetView#tab_selected= instead.
-
#sheet_protection {|@sheet_protection| ... } ⇒ SheetProtection
The sheet protection object for this workbook.
-
#sheet_view {|@sheet_view| ... } ⇒ SheetView
The sheet view object for this worksheet.
-
#show_gridlines ⇒ Object
deprecated
Deprecated.
Use SheetView#show_grid_lines instead.
-
#show_gridlines=(v) ⇒ Boolean
deprecated
Deprecated.
Use SheetView#show_grid_lines= instead.
-
#to_xml_string ⇒ String
Serializes the worksheet object to an xml string This intentionally does not use nokogiri for performance reasons.
Constructor Details
#initialize(wb, options = {}) ⇒ Worksheet
the recommended way to manage worksheets is Workbook#add_worksheet
Creates a new worksheet.
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 183 def initialize(wb, ={}) self.workbook = wb @workbook.worksheets << self @page_marging = @page_setup = @print_options = nil @drawing = @page_margins = @auto_filter = @sheet_protection = @sheet_view = nil @merged_cells = [] @auto_fit_data = [] @conditional_formattings = [] @data_validations = [] @comments = Comments.new(self) self.name = "Sheet" + (index+1).to_s @page_margins = PageMargins.new [:page_margins] if [:page_margins] @page_setup = PageSetup.new [:page_setup] if [:page_setup] @print_options = PrintOptions.new [:print_options] if [:print_options] @rows = SimpleTypedList.new Row @column_info = SimpleTypedList.new Col @protected_ranges = SimpleTypedList.new ProtectedRange @tables = SimpleTypedList.new Table .each do |o| self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end end |
Instance Attribute Details
#auto_filter ⇒ Object
An range that excel will apply an autfilter to “A1:B3” This will turn filtering on for the cells in the range. The first row is considered the header, while subsequent rows are considerd to be data.
67 68 69 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 67 def auto_filter @auto_filter end |
#auto_fit_data ⇒ Array (readonly)
a single auto fit data item is a hash with :longest => [String] and :sz=> [Integer] members.
An array of content based calculated column widths.
56 57 58 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 56 def auto_fit_data @auto_fit_data end |
#column_info ⇒ SimpleTypedList (readonly)
Column info for the sheet
100 101 102 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 100 def column_info @column_info end |
#comments ⇒ SimpleTypedList (readonly)
The comments associated with this worksheet
45 46 47 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 45 def comments @comments end |
#merged_cells ⇒ Object (readonly)
An array of merged cell ranges e.d “A1:B3” Content and formatting is read from the first cell.
61 62 63 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 61 def merged_cells @merged_cells end |
#name ⇒ String
The name of the worksheet
9 10 11 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 9 def name @name end |
#protected_ranges ⇒ SimpleTypedList (readonly)
The recommended way to manage protected ranges is with Worksheet#protect_range
A collection of protected ranges in the worksheet
24 25 26 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 24 def protected_ranges @protected_ranges end |
#rows ⇒ SimpleTypedList (readonly)
The recommended way to manage rows is Worksheet#add_row
The rows in this worksheet
51 52 53 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 51 def rows @rows end |
#tables ⇒ Array (readonly)
The tables in this worksheet
41 42 43 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 41 def tables @tables end |
#workbook ⇒ Workbook
The workbook that owns this worksheet
37 38 39 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 37 def workbook @workbook end |
Class Method Details
.thin_chars ⇒ String
definition of characters which are less than the maximum width of 0-9 in the default font for use in String#count. This is used for autowidth calculations
172 173 174 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 172 def self.thin_chars @thin_chars ||= "^.acefijklrstxyzFIJL()-" end |
Instance Method Details
#[](cell_def) ⇒ Cell, Array
Returns the cell or cells defined using excel style A1:B3 references.
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 586 def [] (cell_def) return rows[cell_def] if cell_def.is_a?(Integer) parts = cell_def.split(':') first = name_to_cell parts[0] if parts.size == 1 first else cells = [] last = name_to_cell(parts[1]) rows[(first.row.index..last.row.index)].each do |r| r.cells[(first.index..last.index)].each do |c| cells << c end end cells end end |
#abs_auto_filter ⇒ Object
The absolute auto filter range
334 335 336 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 334 def abs_auto_filter Axlsx.cell_range(@auto_filter.split(':').collect { |name| name_to_cell(name)}) if @auto_filter end |
#add_chart(chart_type, options = {}) {|chart| ... } ⇒ Object
each chart type also specifies additional options
Adds a chart to this worksheets drawing. This is the recommended way to create charts for your worksheet. This method wraps the complexity of dealing with ooxml drawing, anchors, markers graphic frames chart objects and all the other dirty details.
501 502 503 504 505 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 501 def add_chart(chart_type, ={}) chart = drawing.add_chart(chart_type, ) yield chart if block_given? chart end |
#add_comment(options = {}) ⇒ Object
Shortcut to comments#add_comment
517 518 519 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 517 def add_comment(={}) @comments.add_comment() end |
#add_conditional_formatting(cells, rules) ⇒ Object
Add conditional formatting to this worksheet.
223 224 225 226 227 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 223 def add_conditional_formatting(cells, rules) cf = ConditionalFormatting.new( :sqref => cells ) cf.add_rules rules @conditional_formattings << cf end |
#add_data_validation(cells, data_validation) ⇒ Object
Add data validation to this worksheet.
234 235 236 237 238 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 234 def add_data_validation(cells, data_validation) dv = DataValidation.new(data_validation) dv.sqref = cells @data_validations << dv end |
#add_image(options = {}) {|image| ... } ⇒ Object
Adds a media item to the worksheets drawing
523 524 525 526 527 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 523 def add_image(={}) image = drawing.add_image() yield image if block_given? image end |
#add_row(values = [], options = {}) {|@rows.last| ... } ⇒ Row Also known as: <<
Adds a row to the worksheet and updates auto fit data.
417 418 419 420 421 422 423 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 417 def add_row(values=[], ={}) Row.new(self, values, ) update_column_info @rows.last.cells, .delete(:widths) ||[], .delete(:style) || [] # update_auto_fit_data @rows.last.cells, options.delete(:widths) || [] yield @rows.last if block_given? @rows.last end |
#add_table(ref, options = {}) {|table| ... } ⇒ Object
needs documentation
508 509 510 511 512 513 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 508 def add_table(ref, ={}) table = Table.new(ref, self, ) @tables << table yield table if block_given? table end |
#cells ⇒ Array
convinience method to access all cells in this worksheet
209 210 211 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 209 def cells rows.flatten end |
#col_style(index, style, options = {}) ⇒ Object
You can also specify the style for specific columns in the call to add_row by using an array for the :styles option
Set the style for cells in a specific column
459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 459 def col_style(index, style, ={}) offset = .delete(:row_offset) || 0 @rows[(offset..-1)].each do |r| cells = r.cells[index] next unless cells if cells.is_a?(Array) cells.each { |c| c.style = style } else cells.style = style end end end |
#cols ⇒ Object
returns the sheet data as columnw
446 447 448 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 446 def cols @rows.transpose end |
#column_widths(*widths) ⇒ Object
For updating only a single column it is probably easier to just set the width of the ws.column_info.width directly
This is a helper method that Lets you specify a fixed width for multiple columns in a worksheet in one go. Axlsx is sparse, so if you have not set data for a column, you cannot set the width. Setting a fixed column width to nil will revert the behaviour back to calculating the width for you.
479 480 481 482 483 484 485 486 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 479 def column_widths(*widths) widths.each_with_index do |value, index| next if value == nil Axlsx::validate_unsigned_numeric(value) unless value == nil @column_info[index] ||= Col.new index+1, index+1 @column_info[index].width = value end end |
#dimension ⇒ String
The demensions of a worksheet. This is not actually a required element by the spec, but at least a few other document readers expect this for conversion
276 277 278 279 280 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 276 def dimension dim_start = rows.first.cells.first == nil ? 'A1' : rows.first.cells.first.r dim_end = rows.last.cells.last == nil ? 'AA200' : rows.last.cells.last.r "#{dim_start}:#{dim_end}" end |
#drawing ⇒ Drawing
the recommended way to work with drawings and charts is Worksheet#add_chart
The drawing associated with this worksheet.
374 375 376 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 374 def drawing @drawing || @drawing = Axlsx::Drawing.new(self) end |
#fit_to_page=(v) ⇒ Boolean
304 305 306 307 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 304 def fit_to_page=(v) warn('axlsx::DEPRECIATED: Worksheet#fit_to_page has been depreciated. This value will automatically be set for you when you use PageSetup#fit_to.') fit_to_page? end |
#fit_to_page? ⇒ Boolean
Indicates if the worksheet will be fit by witdh or height to a specific number of pages. To alter the width or height for page fitting, please use page_setup.fit_to_widht or page_setup.fit_to_height. If you want the worksheet to fit on more pages (e.g. 2x2), set PageSetup#fit_to_width and PageSetup#fit_to_height accordingly.
92 93 94 95 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 92 def fit_to_page? return false unless @page_setup @page_setup.fit_to_page? end |
#index ⇒ Integer
The index of this worksheet in the owning Workbook’s worksheets list.
366 367 368 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 366 def index @workbook.worksheets.index(self) end |
#merge_cells(cells) ⇒ Object
Creates merge information for this worksheet. Cells can be merged by calling the merge_cells method on a worksheet.
249 250 251 252 253 254 255 256 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 249 def merge_cells(cells) @merged_cells << if cells.is_a?(String) cells elsif cells.is_a?(Array) cells = cells.sort { |x, y| [x.index, x.row.index] <=> [y.index, y.row.index] } "#{cells.first.r}:#{cells.last.r}" end end |
#name_to_cell(name) ⇒ Cell
returns the column and row index for a named based cell
313 314 315 316 317 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 313 def name_to_cell(name) col_index, row_index = *Axlsx::name_to_indices(name) r = rows[row_index] r.cells[col_index] if r end |
#page_margins {|@page_margins| ... } ⇒ PageMargins
Page margins for printing the worksheet.
118 119 120 121 122 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 118 def page_margins @page_margins ||= PageMargins.new yield @page_margins if block_given? @page_margins end |
#page_setup {|@page_setup| ... } ⇒ PageSetup
Page setup settings for printing the worksheet.
141 142 143 144 145 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 141 def page_setup @page_setup ||= PageSetup.new yield @page_setup if block_given? @page_setup end |
#pn ⇒ String
The part name of this worksheet
348 349 350 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 348 def pn "#{WORKSHEET_PN % (index+1)}" end |
#print_options {|@print_options| ... } ⇒ PrintOptions
Options for printing the worksheet.
163 164 165 166 167 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 163 def @print_options ||= PrintOptions.new yield @print_options if block_given? @print_options end |
#protect_range(cells) ⇒ ProtectedRange
When using an array of cells, a contiguous range is created from the minimum top left to the maximum top bottom of the cells provided.
Adds a new protected cell range to the worksheet. Note that protected ranges are only in effect when sheet protection is enabled.
262 263 264 265 266 267 268 269 270 271 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 262 def protect_range(cells) sqref = if cells.is_a?(String) cells elsif cells.is_a?(SimpleTypedList) cells = cells.sort { |x, y| [x.index, x.row.index] <=> [y.index, y.row.index] } "#{cells.first.r}:#{cells.last.r}" end @protected_ranges << ProtectedRange.new(:sqref => sqref, :name => 'Range#{@protected_ranges.size}') @protected_ranges.last end |
#relationships ⇒ Relationships
The worksheet relationships. This is managed automatically by the worksheet
569 570 571 572 573 574 575 576 577 578 579 580 581 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 569 def relationships r = Relationships.new @tables.each do |table| r << Relationship.new(TABLE_R, "../#{table.pn}") end r << Relationship.new(VML_DRAWING_R, "../#{@comments.vml_drawing.pn}") if @comments.size > 0 r << Relationship.new(COMMENT_R, "../#{@comments.pn}") if @comments.size > 0 r << Relationship.new(COMMENT_R_NULL, "NULL") if @comments.size > 0 r << Relationship.new(DRAWING_R, "../#{@drawing.pn}") if @drawing r end |
#rels_pn ⇒ String
The relationship part name of this worksheet
354 355 356 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 354 def rels_pn "#{WORKSHEET_RELS_PN % (index+1)}" end |
#rId ⇒ String
The relationship Id of thiw worksheet
360 361 362 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 360 def rId "rId#{index+1}" end |
#row_style(index, style, options = {}) ⇒ Object
You can also specify the style in the add_row call
Set the style for cells in a specific row
435 436 437 438 439 440 441 442 443 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 435 def row_style(index, style, ={}) offset = .delete(:col_offset) || 0 rs = @rows[index] if rs.is_a?(Array) rs.each { |r| r.cells[(offset..-1)].each { |c| c.style = style } } else rs.cells[(offset..-1)].each { |c| c.style = style } end end |
#selected ⇒ Object
Use SheetView#tab_selected instead.
Indicates if the worksheet is selected in the workbook It is possible to have more than one worksheet selected, however it might cause issues in some older versions of excel when using copy and paste.
82 83 84 85 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 82 def selected warn('axlsx::DEPRECIATED: Worksheet#selected has been depreciated. This value can get over SheetView#tab_selected.') sheet_view.tab_selected end |
#selected=(v) ⇒ Boolean
Use SheetView#tab_selected= instead.
295 296 297 298 299 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 295 def selected=(v) warn('axlsx::DEPRECIATED: Worksheet#selected= has been depreciated. This value can be set over SheetView#tab_selected=.') Axlsx::validate_boolean v sheet_view.tab_selected = v end |
#sheet_protection {|@sheet_protection| ... } ⇒ SheetProtection
The sheet protection object for this workbook
14 15 16 17 18 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 14 def sheet_protection @sheet_protection ||= SheetProtection.new yield @sheet_protection if block_given? @sheet_protection end |
#sheet_view {|@sheet_view| ... } ⇒ SheetView
The sheet view object for this worksheet
29 30 31 32 33 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 29 def sheet_view @sheet_view ||= SheetView.new yield @sheet_view if block_given? @sheet_view end |
#show_gridlines ⇒ Object
Use SheetView#show_grid_lines instead.
Indicates if the worksheet should show gridlines or not
72 73 74 75 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 72 def show_gridlines warn('axlsx::DEPRECIATED: Worksheet#show_gridlines has been depreciated. This value can get over SheetView#show_grid_lines.') sheet_view.show_grid_lines end |
#show_gridlines=(v) ⇒ Boolean
Use SheetView#show_grid_lines= instead.
Indicates if gridlines should be shown in the sheet. This is true by default.
286 287 288 289 290 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 286 def show_gridlines=(v) warn('axlsx::DEPRECIATED: Worksheet#show_gridlines= has been depreciated. This value can be set over SheetView#show_grid_lines=.') Axlsx::validate_boolean v sheet_view.show_grid_lines = v end |
#to_xml_string ⇒ String
Serializes the worksheet object to an xml string This intentionally does not use nokogiri for performance reasons
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
# File 'lib/axlsx/workbook/worksheet/worksheet.rb', line 532 def to_xml_string str = '<?xml version="1.0" encoding="UTF-8"?>' str << worksheet_node str << sheet_pr_node str << dimension_node @sheet_view.to_xml_string(str) if @sheet_view str << cols_node str << sheet_data_node str << auto_filter_node @sheet_protection.to_xml_string(str) if @sheet_protection str << protected_ranges_node str << merged_cells_node @print_options.to_xml_string(str) if @print_options page_margins.to_xml_string(str) if @page_margins page_setup.to_xml_string(str) if @page_setup str << drawing_node str << legacy_drawing_node str << table_parts_node str << conditional_formattings_node str << data_validations_node str << '</worksheet>' # User reported that when parsing some old data that had control characters excel chokes. # All of the following are defined as illegal xml characters in the xml spec, but for now I am only dealing with control # characters. Thanks to asakusarb and @hsbt's flash of code on the screen! # [#x1-#x8], [#xB-#xC], [#xE-#x1F], [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF], # [#x1FFFE-#x1FFFF], [#x2FFFE-#x2FFFF], [#x3FFFE-#x3FFFF], # [#x4FFFE-#x4FFFF], [#x5FFFE-#x5FFFF], [#x6FFFE-#x6FFFF], # [#x7FFFE-#x7FFFF], [#x8FFFE-#x8FFFF], [#x9FFFE-#x9FFFF], # [#xAFFFE-#xAFFFF], [#xBFFFE-#xBFFFF], [#xCFFFE-#xCFFFF], # [#xDFFFE-#xDFFFF], [#xEFFFE-#xEFFFF], [#xFFFFE-#xFFFFF], # [#x10FFFE-#x10FFFF]. str.gsub(/[[:cntrl:]]/,'') end |