Ruby 入門: 嵌入字符串、% 呈現
string printVal = "value: " + val;
// 或者
string printVal = String.Format("value: {0}", val);
printVal = "value: #{val}"
2 class Employee
3 # 類變量
4 @@companyName = ".org"
5 # 成員變量
6 @empId
7
8 def setEmpId(val)
9 @empId = val
10 end
11
12 def display()
13 # 省略了大括號
14 print "Company: #@@companyName\n"
15 print "Employee ID: #@empId\n"
16 # 僞變量不能省略大括號
17 print "lines: #{__LINE__}\n"
18 end
19 end
20end
21
22emp = Company::Employee.new
23emp.setEmpId("001")
24emp.display
# Company: #@@companyName
print 'Company: #@@companyName'
# 原樣輸出(包括空格和換行)
print '
Company: .org
Employee Id: unknow
'
print "Ruby "% 呈現法""
# 應用 % 呈現方法
print %Q#Ruby "% 呈現"#
print %Q~Ruby "% 呈現"~
print %Q.Ruby "% 呈現".
print %Q*Ruby "% 呈現"*
# 在 % 呈現中插入呈現分隔符
print %Q*\* Ruby "% 呈現"*
# 錯誤
print %Q** Ruby "% 呈現"*
print %QbRuby "% 呈現"b
print %Q<Ruby "% 呈現"<
- %Q 替代雙引號 => %Q#Ruby "% 呈現"# 等同於 "Ruby \"% 呈現\""
- %q 替代單引號
- %r 替代正則表達式 => %r#([\d\w/])*# 等同於 /([\d\w\/)*/
- %s 使嵌入字符串、符號失效 => print %s@#{__LINE__}@ 原樣輸出
- %w 替代字符串數組
這兩天看Rails源碼中的Rakefile時,遇到一句代碼:%x( mysqladmin --user=#{MYSQL_DB_USER} create activerecord_unittest ),雖然大概能猜到這句話是幹什麼的,但是Ruby中到底還有多少種以這樣的%開頭的表示 呢?
相信大家看到最多的應該是:%w,%,%q...下面是我收集的一些%表示法,希望對大家有幫助。
%{String} 用於創建一個使用雙引號括起來的字符串
%Q{String} 用於創建一個使用雙引號括起來的字符串
%q{String} 用於創建一個使用單引號括起來的字符串
%r{String} 用於創建一個正則表達式字面值
%w{String} 用於將一個字符串以空白字符切分成一個字符串數組,進行較少替換
%W{String} 用於將一個字符串以空白字符切分成一個字符串數組,進行較多替換
%s{String} 用於生成一個符號對象
%x{String} 用於執行String所代表的命令
PS:上面幾個%表示法中用{}擴住了String,其實這個{} 只是一種分割符,可以換成別的字符,比如(),那麼%表示法就是%(String),當然還可以是別的字符,對於非括號類型的分割符,左右兩邊要相同, 如%!String!
下面我對這些表示法簡單舉幾個例子:
%{String}用於創建一個使用雙引號括起來的字符串
這個表示法與%Q{String}完全一樣,這邊直接句個例子看結果:
- result = %{hello}
- puts "result is: #{result}, Type is:#{result.class}"
%Q{String}用於創建一個使用雙引號括起來的字符串
%q{String}用於創建一個使用單引號括起來的字符串
從說明中可以看出這兩個表示法的區別就是一個使用雙引號,一個使用單引號。使用雙引號的字符串會對字符串中的變量做較多替換,而單引號則做較少的替換,具 體看例子。先看%Q{String}:
- world = "world"
- result = %Q{hello #{world}}
- puts "result is: #{result}, Type is:#{result.class}"
換成%q{String}:
- world = "world"
- result = %q{hello #{world}}
- puts "result is: #{result}, Type is:#{result.class}"
result is: hello #{world}, Type is:String
從上面的結果可以看出,較少替換的情況下,#{world}被解析成了字符串,而不會去計算這個變量中的值。
%r{String}用於創建一個正則表達式字面值
就像使用/reg/方式一樣,看代碼:
- result = %r{world}
- puts result =~ "hello world"
- puts "result is: #{result}, Type is:#{result.class}"
result is: (?-mix:world), Type is:Regexp
可以看出,world從第6個字符開始匹配
%w{String}用於將一個字符串以空白字符切分成一個字符串數組,進行較少替換
%W{String}用於將一個字符串以空白字符切分成一個字符串數組,進行較多替換
這兩個應該是大家見過最多的,用這個方式構造數組,可以省下一些逗號,Ruby真 是會慣壞大家,以後大家都不用標點符號了。
同樣給一個簡單的例子:
- result = %w{hello world}
- puts "result is: #{result}, Type is:#{result.class}, length is:#{result.length}"
%s{String}用於生成一個符號對象
直接先上代碼:
- result = %s{hello world}
- puts "result is: #{result}, Type is:#{result.class}"
- sym = :"hello world"
- puts "the two symbol is the same: #{sym == result}"
result is: hello world, Type is:Symbol
the two symbol is the same: true
可以看出,這兩中方式生成的symbol對象完全一樣
%x{String}用於執行String所代表的命令
比如:
%x{notepad.exe}可以啓動windows下的記事本,這裏我就不列結果了(那是一個大家熟悉的窗口)。
- file1 = File.new("one") # Open for reading
- file2 = File.new("two","w") # Open for writing
- file1 = File.new("one") # Open for reading file2 = File.new("two", "w") # Open for writing
- file = File.new("three", 0755,File::CREAT|File::WRONLY)
- file = File.new("three", 0755, File::CREAT|File::WRONLY)
出於對操作系統和運行環境的考慮,如果你打開了一個文件的話,你就必須關閉它。當你打開一個文件用於寫時,你更應該這樣做,從而才能免於丟失數據.close方法就是關閉一個文件:
- out = File.new("captains.log","w")
- # Process as needed...
- out.close
- out = File.new("captains.log", "w") # Process as needed... out.close
這裏還有一個open方法,它的最簡單的形式是和new同義的:
- trans = File.open("transactions","w")
- trans = File.open("transactions","w")
但是open方法還能夠帶一個block作爲參數,當存在block時,打開的文件將會做爲一個參數傳遞給block.這時這個文件將會在這個block的作用域裏,保持打開,直到block結束時,自動關閉:
- File.open("somefile","w")do |file|
- file.puts "Line 1"
- file.puts "Line 2"
- file.puts "Third and final line"
- end
- File.open("somefile","w") do |file| file.puts "Line 1" file.puts "Line 2" file.puts "Third and final line" end
2 更新文件
假設我們想要打開一個文件用於讀和寫,簡單的加一個'+'號到file mode就行了:
- f1 = File.new("file1","r+")
- # Read/write, starting at beginning of file.
- f2 = File.new("file2","w+")
- # Read/write; truncate existing file or create a new one.
- f3 = File.new("file3","a+")
- # Read/write; start at end of existing file or create a
- # new one.
- f1 = File.new("file1", "r+") # Read/write, starting at beginning of file. f2 = File.new("file2", "w+") # Read/write; truncate existing file or create a new one. f3 = File.new("file3", "a+") # Read/write; start at end of existing file or create a # new one.
3 追加一個文件
假設我們想要追加一段信息到一個存在文件,當我們打開文件時使用'a'作爲file mode就行了:
- logfile = File.open("captains_log","a")
- # Add a line at the end, then close.
- logfile.puts "Stardate 47824.1: Our show has been canceled."
- logfile.close
- logfile = File.open("captains_log", "a") # Add a line at the end, then close. logfile.puts "Stardate 47824.1: Our show has been canceled." logfile.close
4隨機存取一個文件
如果你想隨即存取一個文件,你能夠使用seek方法,它是File從Io繼承而來的.它的最簡單的使用就是指定一個字節位置.這個位置是相對於文件開始的位置(開始的位置是0):
- # myfile contains only: abcdefghi
- file = File.new("myfile")
- file.seek(5)
- str = file.gets # "fghi"
- # myfile contains only: abcdefghi file = File.new("myfile") file.seek(5) str = file.gets # "fghi"
如果你能確定每一行都是固定的長度,你就能seek指定的行:
- # Assume 20 bytes per line.
- # Line N starts at byte (N-1)*20
- file = File.new("fixedlines")
- file.seek(5*20) # Sixth line!
- # Elegance is left as an exercise.
- # Assume 20 bytes per line. # Line N starts at byte (N-1)*20 file = File.new("fixedlines") file.seek(5*20) # Sixth line! # Elegance is left as an exercise.
- file = File.new("somefile")
- file.seek(55) # Position is 55
- file.seek(-22, IO::SEEK_CUR) # Position is 33
- file.seek(47, IO::SEEK_CUR) # Position is 80
- file = File.new("somefile") file.seek(55) # Position is 55 file.seek(-22, IO::SEEK_CUR) # Position is 33 file.seek(47, IO::SEEK_CUR) # Position is 80
你也能從文件的結束位置開始搜索:
- file.seek(-20, IO::SEEK_END) # twenty bytes from eof
- file.seek(-20, IO::SEEK_END) # twenty bytes from eof
- file.seek(20)
- pos1 = file.tell # 20
- file.seek(50, IO::SEEK_CUR)
- pos2 = file.pos # 70
- file.seek(20) pos1 = file.tell # 20 file.seek(50, IO::SEEK_CUR) pos2 = file.pos # 70
5 操作二進制文件
在很久以前,c語言通過在file mode後附加一個'b'來表示將文件用二進制模式打開.在今天,二進制文件的處理已經沒有那麼麻煩了。在ruby中,一個字符串很容易保存一個二進制數據,而且也不用通過任何特殊的方式來讀文件.
可是在windows下是例外,在他下面,二進制文件和文本文件的不同是,在二進制mode下,結束行不能被轉義爲一個單獨的換行,而是被保存爲一個回車換行對.
另外的不同是,在文本模式下 control-Z被作爲文件的結束:
- # Create a file (in binary mode)
- File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") }
- # Above note the embedded octal 032 (^Z)
- # Read it as binary
- str = nil
- File.open("myfile","rb") {|f| str = f.sysread(15) }
- puts str.size # 11
- # Read it as text
- str = nil
- File.open("myfile","r") {|f| str = f.sysread(15) }
- puts str.size # 5
- # Create a file (in binary mode) File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") } # Above note the embedded octal 032 (^Z) # Read it as binary str = nil File.open("myfile","rb") {|f| str = f.sysread(15) } puts str.size # 11 # Read it as text str = nil File.open("myfile","r") {|f| str = f.sysread(15) } puts str.size # 5
再看下面的代碼:
- # Input file contains a single line: Line 1.
- file = File.open("data")
- line = file.readline # "Line 1.\n"
- puts "#{line.size} characters." # 8 characters
- file.close
- file = File.open("data","rb")
- line = file.readline # "Line 1.\r\n"
- puts "#{line.size} characters." # 9 characters 二進制模式的結尾是一個回車換行對.
- file.close
- # Input file contains a single line: Line 1. file = File.open("data") line = file.readline # "Line 1.\n" puts "#{line.size} characters." # 8 characters file.close file = File.open("data","rb") line = file.readline # "Line 1.\r\n" puts "#{line.size} characters." # 9 characters 二進制模式的結尾是一個回車換行對. file.close
- file = File.open("data")
- file.binmode
- line = file.readline # "Line 1.\r\n"
- puts "#{line.size} characters." # 9 characters
- file.close
- file = File.open("data") file.binmode line = file.readline # "Line 1.\r\n" puts "#{line.size} characters." # 9 characters file.close
- input = File.new("myfile",'a+')
- output = File.new("outfile",'a+')
- instr = input.sysread(10);
- puts instr
- bytes = output.syswrite("This is a test.")
- input = File.new("myfile",'a+') output = File.new("outfile",'a+') instr = input.sysread(10); puts instr bytes = output.syswrite("This is a test.")
如果文件指針已經到達文件的結尾時,sysread方法將會拋出一個異常.
這邊要注意 Array 的pack和string的unpack方法,對於處理二進制數據非常有用.
=======================================================
讀文件:
第一種方法:
$result='d:\\rs.txt'
File.open($result, "r") do |file|
file.each_line do |line|
if line.length>20
puts line.chop.length #去掉最後一個換行字符,並顯示該行實際字符串的長度
puts line
end
end
end
第二種方法:
filename='d:\\rs.txt'
while File.exists?(filename) #如果源文件存在就執行下面的操作
file=File.open(filename,'r')
while (lines=file.gets)
puts lines
end
寫文件:
$filename="C:\\Automation\\rss"+".txt"
$logfile = File.new($filename,"a")
iCount=0
while(iCount<10) //循環寫入10行
$logfile.puts "http://xxxx/rs#{iCount}.xml"
iCount=iCount+1
end
今天又笨了一次,由於要比較兩個文件的不同,於是考慮用ruby來寫個腳本
實現,剛開始的時候使用雙重
File.open($file1, "r") do |file1|
file1.each_line do |line1|
總是報錯,
後來改成先把文件讀到一個數組裏,然後循環比較,成功.
其實這是個笨方法,在unix下使用三個命令就可以完成了.
1.先使用sort指令將文件中的數據按照要求的索引進行排序,
2.然後使用uniq指令將重複數據去掉
3.再使用diff命令就可以了.
========================================
ruby讀寫文本文件的簡單例子,除了演示文本文件的讀寫外,這段ruby程序可以從文本文件中刪除包含某些字符串的行。
用法:ruby delline.rb 文件名 字符串1 字符串2 字符串n
將刪除同時包含字符串1 字符串2 字符串n的行。
ruby的開發環境這裏下載
http://www.ruby-lang.org/en/downloads/
直接下載最近的穩定版Windows安裝包
http://rubyforge.org/frs/download.php/29263/ruby186-26.exe
代碼如下
- ifARGV.length<2then
- puts "USAGE: ruby delline.rb text_file_name str1 [str2 ...]"
- exit
- end
- i_file_name = ARGV[0]
- i_file_name_bak = i_file_name +".bak"
- if FileTest.exist?(i_file_name)then
- File.rename(i_file_name,i_file_name_bak)
- else
- puts "File #{i_file_name} was not found"
- exit
- end
- i_file = File.new(i_file_name_bak,"r")
- o_file = File.new(i_file_name,"w")
- i_file.each_line do |line|
- delete_flag =true
- 1.upto(ARGV.length - 1) do |x|
- if !line.include?(ARGV[x]) then
- delete_flag =false
- break
- end
- end
- o_file.puts lineif !delete_flag
- end
- i_file.close
- o_file.close
File.open("cmd.txt","r") do |file|
while line=file.gets
puts line
end
end
puts
file=File.new("cmd.txt","r")
file.each_line do |line|
puts line
end
IO.foreach("cmd.txt") do |line|
puts line if line =~ /target/
puts line if line !~ /target/
end
# Another way...
file = File.new("cmd.txt")
file.each do |line|
puts line if line =~ /target/
end
arr = IO.read("cmd.txt")
bytes = arr.size
puts "myfile has #{bytes} bytes in it."
arr = IO.readlines("cmd.txt")
puts arr
lines = arr.size
puts "myfile has #{lines} lines in it."
file2=File.new("cmd.txt");
puts File.expand_path("cmd.txt")
file = File.new("cmd.txt")
e_count = 0
file.each_byte do |byte|
e_count += 1 if byte == ?e
end
puts File.exist?("testR.txt")
file1=File.new("testR.txt","w") #沒有文件則會自動創建
puts File.exist?("testR.txt")
puts file1.write("ttt333\nttt444\n")
字符串當文件用.rb
require 'stringio'
ios = StringIO.new("abcdefghijkl\nABC\n123")
ios.seek(5)
ios.puts("xyz")
puts ios.tell # 8
puts ios.string.dump # "abcdexyzijkl\nABC\n123"
c = ios.getc
puts "c = #{c}" # c = 105
ios.ungetc(?w)
puts ios.string.dump # "abcdexyzwjkl\nABC\n123"
puts "Ptr = #{ios.tell}"
s1 = ios.gets # "wjkl"
s2 = ios.gets # "ABC"