rubyonrails:使用 Ruby 处理文本

  和 Perl 和 Python 类似Ruby 拥有出色功能种强大文本处理语言本文简单介绍了 Ruby 文本数据处理功能以及如何使用 Ruby 语言有效处理区别格式文本数据无论是 CSV 数据还是 XML 数据

  Ruby

  常用缩略词

  CSV:逗号分隔值

  REXML:Ruby Electric XML

  XML:可扩展标记语言

  Ruby 中 String 是容纳、比较和操作文本数据种强大思路方法在 Ruby 中String 是个类可以通过 String:: 或向它分配个字面值将它例子化

  向 Strings 赋值时可以使用单引号(')或双引号(")来包围值单引号和双引号在为 Strings 赋值时有几个差别双引号支持转义序列使用个前置反斜杠()并支持在串中使用 #{} 操作符计算表达式而单引号引用串则是简单直接文字

  清单 1 是个举例

  清单 1. 处理 Ruby 串:定义

 
message = 'Heal the World…' 
 
puts message 
 
message1 = "Take home Rs #{100*3/2} " 
 
puts message1 
 
Output : 
 
# ./1.rb 
 
# Heal the World… 
 
# Take home Rs 150 


  这里串使用对单引号定义第 2个串使用对双引号定义在第 2个串中#{} 中表达式在显示前计算

  另种有用串定义思路方法通常用于多行串定义

  从现在开始我将使用交互式 Ruby 控制台 irb>> 进行介绍说明 Ruby 安装也应该安装该控制台如果没有安装建议您获取 irb Ruby gem 并安装它Ruby 控制台是学习 Ruby 及其模块个非常有用工具安装的后可以使用 irb>> 命令运行它

  清单 2. 处理 Ruby 串:定义多个

 
irb>> str = >>EOF 
 
irb>> "hello world 
 
irb>> "how do you feel? 
 
irb>> "how r u ? 
 
irb>> EOF 
 
"hello, worldnhow do you feel?nhow r u?n" 
 
irb>> puts str 
 
hello, world 
how do you feel? 
how r u? 


  在 清单 2 中>>EOF 和 EOF 中所有内容都视为部分包括 n(换行)

  Ruby String 类有组强大思路方法用于操作和处理存储在它们的中数据清单 3、4 和 5 中举例展示了部分思路方法

  清单 3. 处理 Ruby 串:连接

 
irb>> str = "The world for a horse"  # String initialized with a value 
 
The world for a horse 
 
irb>> str*2           # Multiplying with an eger s a 
                     #   containing that many times 
                     # of the old . 
 
The world for a horseThe world for a horse 
 
irb>> str + " Who said it ? "   # Concatenation of s using the '+' operator 
 
The world for a horse Who said it ? 
 
irb>> str<<" is it? "  # Concatenation using the '<<' operator 
 
The world for a horse is it? 


  提取子串并操作多个部分

  清单 4. 处理 Ruby 串:提取并操作

 
irb>> str[0] # The '' operator can be used to extract subs, just 
            # like accessing entries in an .gif' />. 
            # The index starts from 0. 
84  # A single index s the ascii value 
            # of the character at that position 
 
irb>> str[0,5] # a range can be specied as a pair. The first is the starting 
            # index , second is the length of the sub from the 
            # starting index. 
 
The w 
 
irb>> str[16,5]="Ferrari"  # The same '' operator can be used 
                 # to replace subs in a  
                 # by using the assignment like '=' 
irb>>str 
 
The world for a Ferrari 
 
Irb>> str[10..22] # The range can also be specied using [x1..x2] 
 
for a Ferrari 
 
irb>> str[" Ferrari"]=" horse" # A sub can be specied to be replaced by a  
                # . Ruby s are elligent enough to adjust the 
                # size of the  to make up for the replacement . 
 
irb>> s 
 
The world for a horse 
 
irb>> s.split    # Split, splits the  based on the given delimiter 
                # default is a whitespace, ing an .gif' /> of s. 
 
["The", "world", "for", "a", "horse"] 
 
irb>> s.each(' ') { |str| p str.chomp(' ') } 
 
                # each , is a way of block processing the 
     #  splitting it on a record separator 
     # Here, I use chomp to cut off the trailing space 
 
"The" 
"world" 
"for" 
"a" 
"horse" 


  Ruby String 类还可以使用许多其他实用思路方法这些思路方法可以更改大小写、获取串长度、删除记录分隔符、扫描串、加密、解密等个有用思路方法是 freeze该思路方法可以使串变得不可修改对 String str 该思路方法(str.freeze)的后str 将不能被修改

  Ruby 还有些称为 “析构器(destructor)” 思路方法以感叹号(!)结尾思路方法将永久修改常规思路方法(结尾没有感叹号)修改并返回它们副本而带有感叹号思路方法直接修改它们

  清单 5. 处理 Ruby 串:永久修改

 
irb>> str = "hello, world" 
 
hello, world 
 
irb>> str.up 
 
HELLO, WORLD 
 
irb>>str     # str, res as is. 
 
Hello, world 
 
irb>> str.up!    # here, str gets modied by the '!' at the end of 
                # up. 
HELLO, WORLD 
 
irb>> str 
 
HELLO, WORLD 


  在 清单 5 中str 中串由 up! 思路方法修改但 up 思路方法只返回大小写修改后串副本这些 ! 思路方法有时很有用

  Ruby Strings 功能非常强大数据被捕获进 Strings 中后您就能够任意使用多种思路方法轻松有效地处理这些数据

  处理 CSV 文件

  CSV 文件是表示表格式数据种很常见思路方法表格式通常用作从电子表格导出数据(比如带有详细信息联系人列表)格式

  Ruby 有个强大可以用于处理这些文件csv 是负责处理 CSV 文件 Ruby 模块它拥有创建、读取和解析 CSV 文件思路方法

  清单 6 展示了如何创建个 CSV 文件并使用 Ruby csv 模块来解析文件

  清单 6. 处理 CSV 文件:创建并解析个 CSV 文件

 
require 'csv' 
 
writer = CSV.open('mycsvfile.csv','w') 
 
begin 
 
 pr "Enter Contact Name: " 
 
 name = STDIN.gets.chomp 
 
 pr "Enter Contact No: " 
 
 num = STDIN.gets.chomp 
 
 s = name+" "+num 
 
 row1 = s.split 
 
 writer << row1 
 
 pr "Do you want to add more ? (y/n): " 
 
 ans = STDIN.gets.chomp 
 
end while ans != "n" 
 
writer.close 
 
file = File.('mycsvfile.csv') 
 
lines = file.readlines 
 
parsed = CSV.parse(lines.to_s) 
 
p parsed 
 
puts "" 
 
puts "Details of Contacts stored are as follows..." 
 
puts "" 
 
puts "-------------------------------" 
 
puts "Contact Name | Contact No" 
 
puts "-------------------------------" 
 
puts "" 
 
CSV.open('mycsvfile.csv','r') do |row| 
 
 puts row[0] + " | " + row[1] 
 
 puts "" 
end 


  清单 7 显示了输出:

  清单 7. 处理 CSV 文件:创建并解析个 CSV 文件输出

 
Enter Contact Name: Santhosh 
 
Enter Contact No: 989898 
 
Do you want to add more ? (y/n): y 
 
Enter Contact Name: Sandy 
 
Enter Contact No: 98988 
 
Do you want to add more ? (y/n): n 
 
Details of Contacts stored are as follows... 
 
--------------------------------- 
Contact Name | Contact No 
--------------------------------- 
 
Santhosh | 989898 
 
Sandy | 98988 


  让我们快速检查下这个举例

  首先包含 csv 模块(require 'csv')

  要创建个新 CSV 文件 mycsvfile.csv使用 CSV.open 打开它这返回个写入器(writer)对象

  这个举例创建了个 CSV 文件该文件包含个简单联系人列表存储联系人姓名及其电话号码在循环中用户被要求输入联系人姓名和电话号码姓名和电话号码被连接为然后分割为含两个这个传递到写入器对象以便写入 CSV 文件这样对 CSV 值就存储为文件中

  循环结束后任务也就完成了现在关闭写入器文件中数据得以保存

  下步是解析创建 CSV 文件

  打开和解析该文件种思路方法是使用新 CSV 文件名称创建个新 File 对象

   readlines 思路方法将文件中所有行读入个名为 lines

  通过 lines.to_s 将 lines 转换为个 String 对象然后将这个 String 对象传递到 CSV.parse 思路方法该思路方法解析 CSV 数据并将其内容返回为个包含

  下面介绍打开和解析该文件种思路方法以读取模式使用 CSV.open 再次打开文件这返回个行使用某种格式打印每个行以显示联系人细节这里每个行对应文件中

  如您所见Ruby 提供个强大模块来处理 CSV 文件和数据

  处理 XML 文件

  对于 XML 文件Ruby 提供个名为 REXML 强大内置库这个库可以用于读取和解析 XML 文档

  查看以下 XML 文件并试图用 Ruby 和 REXML 来解析它

  下面是个简单 XML 文件列示个在线购物中心典型购物车中内容它拥有以下元素:

  cart —— 根元素

  user —— 购货用户

  item —— 用户添加到购物车中商品项

  id, price 和 quantity —— 项目子元素

  清单 8 展示了这个 XML 结构:

  清单 8. 处理 XML 文件:举例 XML 文件

 
<cart id="userid"> 
 
<item code="item-id"> 
 
 <price> 
 
 <price/unit> 
 
 </price> 
 
 <qty> 
 
 <number-of-units> 
 
 </qty> 
 
</item> 
 
</cart> 


  从 下载 部分获取这个举例 XML 文件现在加载这个 XML 文件并使用 REXML 解析文件树

  清单 9. 处理 XML 文件:解析 XML 文件

 
require 'rexml/document' 
 
 REXML 
 
file = File.('shoppingcart.xml') 
 
doc = Document.(file) 
 
root = doc.root 
 
puts "" 
 
puts "Hello, #{root.attributes['id']}, Find below the bill generated for your purchase..." 
 
puts "" 
 
sumtotal = 0 
 
puts "-----------------------------------------------------------------------" 
 
puts "ItemttQuantityttPrice/unitttTotal" 
 
puts "-----------------------------------------------------------------------" 
 
root.each_element('//item') { |item| 
 
code = item.attributes['code'] 
 
qty = item.elements["qty"].text.split(' ') 
 
price = item.elements["price"].text.split(' ') 
 
total = item.elements["price"].text.to_i * item.elements["qty"].text.to_i 
 
puts "#{code}tt #{qty}tt     #{price}tt     #{total}" 
 
puts "" 
 
sumtotal  total 
 
} 
 
puts "-----------------------------------------------------------------------" 
 
puts "tttttt   Sum total : " + sumtotal.to_s 
 
puts "-----------------------------------------------------------------------" 


  清单 10 显示输出

  清单 10. 处理 XML 文件:解析 XML 文件输出

 
Hello, santhosh, Find below the bill generated for your purchase... 
 
------------------------------------------------------------------------- 
Item      Quantity        Price/unit       Total 
------------------------------------------------------------------------- 
CS001       2             100           200 
 
CS002       5             200           1000 
 
CS003       3             500           1500 
 
CS004       5             150           750 
 
------------------------------------------------------------------------- 
                             Sum total : 3450 
-------------------------------------------------------------------------- 


  清单 9 解析这个购物车 XML 文件并生成个账单该账单显示项目合计和采购总计(见 清单 10)

  下面我们具体介绍操作过程

  首先包含 Ruby REXML 模块该模块拥有解析 XML 文件思路方法

  打开 shoppingcart.xml 文件并从该文件创建个 Document 对象该对象包含解析后 XML 文件

  将文档根分配给元素对象 root这将指向 XML 文件中 cart 标记

  每个元素对象拥有个属性对象该属性对象是元素属性 hash 表其中属性名称作为键名属性值作为键值这里root.attributes['id'] 将提供 root 元素 id 属性值(本例中为 userid)

  下面将 sumtotals 化为 0 并打印标头

  每个元素对象还有个对象 elements该对象拥有 each 和 思路方法以便访问子元素这个对象遍历所有带有 item 名称(通过 XPath 表达式 //item 指定) root 元素子元素每个元素还有个属性 text该属性容纳元素文本值

  下获取 item 元素 code 属性以及 price 和 qty 元素文本值然后计算项目合计(Total)将详细信息打印到账单并将项目合计添加到采购总计(Sum total)

  最后打印采购总计

  这个举例展示了使用 REXML 和 Ruby 解析 XML 文件有多么简单!同样在运行中生成 XML 文件添加和删除元素及它们属性也很简单

  清单 11. 处理 XML 文件:生成 XML 文件

 
doc = Document. 
 
doc.add_element("cart1", {"id" => "user2"}) 
 
cart = doc.root.elements[1] 
 
item = Element.("item") 
 
item.add_element("price") 
 
item.elements["price"].text = "100" 
 
item.add_element("qty") 
 
item.elements["qty"].text = "4" 
 
cart .elements << item 


  清单 11 中代码通过创建个 cart 元素、个 item 元素和它子元素来创建 XML 结构然后使用值填充这些子元素并将它们添加到 Document 根

  类似地要删除元素和属性使用 Elements 对象 delete_element 和 delete_attribute 思路方法

  以上举例中思路方法称为树解析(tree parsing)种 XML 文档解析思路方法称为流解析(stream parsing)“流解析” 比 “树解析” 更快可以用于要求快速解析情况“流解析” 是基于事件它使用监听器当解析流遇到个标记时它将监听器并执行处理

  清单 12 展示了个举例:

  清单 12. 处理 XML 文件:流解析

 
require 'rexml/document' 
 
require 'rexml/streamlistener' 
 
 REXML 
 
 Listener 
 
  StreamListener 
 
 def tag_start(name, attributes) 
 
  puts "Start #{name}" 
 
 end 
 
 def tag_end(name) 
 
  puts "End #{name}" 
 
 end 
 
end 
 
listener = Listener. 
 
parser = Parsers::StreamParser.(File.("shoppingcart.xml"), listener) 
 
parser.parse 


  清单 13 显示输出:

  清单 13. 处理 XML 文件:流解析输出

 
Start cart 
 
Start item 
 
Start price 
 
End price 
 
Start qty 
 
End qty 
 
End item 
 
Start item 
 
Start price 
 
End price 
 
Start qty 
 
End qty 
 
End item 
 
Start item 
 
Start price 
 
End price 
 
Start qty 
 
End qty 
 
End item 
 
Start item 
 
Start price 
 
End price 
 
Start qty 
 
End qty 
 
End item 
 
End cart 




  这样REXML 和 Ruby 联合起来为您提供种非常有效和直观地处理和操作 XML 数据强大思路方法

  结束语

  Ruby 拥有组很好内置库和外部库支持快速、强大和有效文本处理您可以利用该功能简化和改进可能遇到各种文本数据处理工作本文只是 Ruby 文本处理功能简要介绍您可以进步深入了解该功能

  毋庸置疑Ruby 是您需要个强大工具



  本文举例源代码或素材下载

Tags:  rubydj ruby教程 ruby台湾 rubyonrails

延伸阅读

最新评论

发表评论