使用Ruby來處理文本的教程_ruby專題

來源:互聯網
上載者:User

與 Perl 和 Python 類似,Ruby 擁有出色的功能,是一種強大的文本處理語言。本文簡單介紹了 Ruby 的文本資料處理功能,以及如何使用 Ruby 語言有效處理不同格式的文本資料,無論是 CSV 資料還是 XML 資料。
Ruby 字串
常用縮減詞

  •     CSV:逗號分隔值
  •     REXML:Ruby Electric XML
  •     XML:可延伸標記語言 (XML)

Ruby 中的 String 是容納、比較和操作文本資料的一種強大方法。在 Ruby 中,String 是一個類,可以通過調用 String::new 或向它分配一個字面值將它執行個體化。

向 Strings 賦值時,可以使用單引號(')或雙引號(")來包圍值。單引號和雙引號在為 Strings 賦值時有幾個差別。雙引號支援逸出序列使用一個前置反斜線(\)並支援在字串中使用 #{} 操作符計算運算式。而單引號引用的字串則是簡單直接的文字。

清單 1 是一個樣本。
清單 1. 處理 Ruby 字串:定義字串

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

這裡,第一個字串使用一對單引號定義,第二個字串使用一對雙引號定義。在第二個字串中,#{} 中的運算式在顯示前計算。

另一種有用的字串定義方法通常用於多行字串定義。

從現在開始,我將使用互動式 Ruby 控制台 irb>> 進行說明。您的 Ruby 安裝也應該安裝該控制台。如果沒有安裝,建議您擷取 irb Ruby gem 並安裝它。Ruby 控制台是學習 Ruby 及其模組的一個非常有用的工具。安裝之後,可以使用 irb>> 命令運行它。
清單 2. 處理 Ruby 字串:定義多個字串

irb>> str = >>EOFirb>> "hello worldirb>> "how do you feel?irb>> "how r u ?irb>> EOF"hello, world\nhow do you feel?\nhow r u?\n"irb>> puts strhello, worldhow 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 valueThe world for a horseirb>> str*2      # Multiplying with an integer returns a            # new string containing that many times           # of the old string.The world for a horseThe world for a horseirb>> str + " Who said it ? "  # Concatenation of strings using the '+' operatorThe world for a horse Who said it ?irb>> str<<" is it? " # Concatenation using the '<<' operatorThe world for a horse is it?

提取子字串並操作字串的多個部分
清單 4. 處理 Ruby 字串:提取並操作

irb>> str[0] # The '[]' operator can be used to extract substrings, just       # like accessing entries in an array.      # The index starts from 0.84 # A single index returns the ascii value      # of the character at that positionirb>> str[0,5] # a range can be specified as a pair. The first is the starting       # index , second is the length of the substring from the      # starting index.The wirb>> str[16,5]="Ferrari" # The same '[]' operator can be used         # to replace substrings in a string         # by using the assignment like '[]='irb>>strThe world for a FerrariIrb>> str[10..22] # The range can also be specified using [x1..x2] for a Ferrariirb>> str[" Ferrari"]=" horse" # A substring can be specified to be replaced by a new        # string. Ruby strings are intelligent enough to adjust the        # size of the string to make up for the replacement string.irb>> sThe world for a horseirb>> s.split  # Split, splits the string based on the given delimiter        # default is a whitespace, returning an array of strings.["The", "world", "for", "a", "horse"]irb>> s.each(' ') { |str| p str.chomp(' ') }        # each , is a way of block processing the   # string 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, worldirb>> str.upcaseHELLO, WORLDirb>>str   # str, remains as is.Hello, worldirb>> str.upcase!  # here, str gets modified by the '!' at the end of         # upcase.HELLO, WORLDirb>> strHELLO, WORLD

在 清單 5 中,str 中的字串由 upcase! 方法修改,但 upcase 方法只返回大小寫修改後的字串副本。這些 ! 方法有時很有用。

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 print "Enter Contact Name: " name = STDIN.gets.chomp print "Enter Contact No: " num = STDIN.gets.chomp s = name+" "+num row1 = s.split writer << row1 print "Do you want to add more ? (y/n): " ans = STDIN.gets.chompend while ans != "n"writer.closefile = File.new('mycsvfile.csv')lines = file.readlinesparsed = CSV.parse(lines.to_s)p parsedputs ""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: SanthoshEnter Contact No: 989898Do you want to add more ? (y/n): yEnter Contact Name: SandyEnter Contact No: 98988Do you want to add more ? (y/n): nDetails of Contacts stored are as follows...---------------------------------Contact Name | Contact No---------------------------------Santhosh | 989898Sandy | 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'include REXMLfile = File.new('shoppingcart.xml')doc = Document.new(file)root = doc.rootputs ""puts "Hello, #{root.attributes['id']}, Find below the bill generated for your purchase..."puts ""sumtotal = 0puts "-----------------------------------------------------------------------"puts "Item\t\tQuantity\t\tPrice/unit\t\tTotal"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_iputs "#[code]\t\t #{qty}\t\t   #{price}\t\t   #{total}"puts ""sumtotal += total}puts "-----------------------------------------------------------------------"puts "\t\t\t\t\t\t  Sum total : " + sumtotal.to_sputs "-----------------------------------------------------------------------"

清單 10 顯示輸出。
清單 10. 處理 XML 檔案:解析 XML 檔案輸出

Hello, santhosh, Find below the bill generated for your purchase...-------------------------------------------------------------------------Item   Quantity    Price/unit    Total-------------------------------------------------------------------------CS001    2       100      200CS002    5       200      1000CS003    3       500      1500CS004    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.newdoc.add_element("cart1", {"id" => "user2"})cart = doc.root.elements[1]item = Element.new("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'include REXMLclass Listener include StreamListener def tag_start(name, attributes) puts "Start #{name}" end def tag_end(name) puts "End #{name}" endendlistener = Listener.newparser = Parsers::StreamParser.new(File.new("shoppingcart.xml"), listener)parser.parse

清單 13 顯示輸出:
清單 13. 處理 XML 檔案:流解析輸出

Start cartStart itemStart priceEnd priceStart qtyEnd qtyEnd itemStart itemStart priceEnd priceStart qtyEnd qtyEnd itemStart itemStart priceEnd priceStart qtyEnd qtyEnd itemStart itemStart priceEnd priceStart qtyEnd qtyEnd itemEnd cart

這樣,REXML 和 Ruby 聯合起來為您提供一種非常有效和直觀地處理和操作 XML 資料的強大方法。

結束語

Ruby 擁有一組很好的內建庫和外部庫,支援快速、強大和有效文本處理。您可以利用該功能簡化和改進可能遇到的各種文本資料處理工作。本文只是 Ruby 的文本處理功能的簡要介紹,您可以進一步深入瞭解該功能。

毋庸置疑,Ruby 是您需要的一個強大工具。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.