ruby: 嵌入字符串、% 呈现、ruby文件读写ruby way之IO之一

Ruby 入门: 嵌入字符串、% 呈现

嵌入字符串
在 Ruby 中我非常喜欢的一个功能就是嵌入字符串,所谓嵌入就是指直接将变量写入引号的形式,这样做的好处是直观和节约了连字符出现的频率。比如在 C# 中我们可以编写下面的代码。
string  val  =   " value " ;
string  printVal  =   " value:  "   +  val;
//  或者
string  printVal  =  String.Format( " value: {0} " , val);

但在 Ruby 中可以采用嵌入字符串的形式来节约一些代码(我想这里正体现了 Ruby 的优雅)。
val  =   " Value "
printVal 
=   " value: #{val} "

嵌入字符串的形式是非常简单的,只需将变量名放到 # 字符后面的大括号中就可以了。而对于类变量、成员变量和全局变量来说,甚至可以连大括号也可以省略掉(伪变量则不能省略大括号)。
 1 module Company
 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
20 end
21
22 emp  =  Company :: Employee . new
23 emp . setEmpId( " 001 " )
24 emp . display

Ruby 的嵌入字符串只能在双引号中使用,因为解释器会原样输出单引号中的内容。Ruby 的单引号就有点 C# 中的 @"" 的感觉。
#  原样输出
#   Company: #@@companyName

print   ' Company: #@@companyName '
#  原样输出(包括空格和换行)
print   '
      Company:     .org
      Employee Id: unknow
'

% 呈现

Ruby 的另一个酷酷的功能就是 % 呈现方法,这是一种替代引号或其它分隔字符的表示方法。下面第一句直接在双引号内插入双引号是错误的,但使用 % 呈现后就可以直接在字符串内插入双引号了。
#  错误
print   " Ruby  " %  呈现法 ""
#  应用 % 呈现方法
print   %Q # Ruby "% 呈现"#

在 % 呈现中,Q 是呈现标识、! 是呈现分隔符。呈现标识声明替代哪种分隔字符,! 则是一个自定义的分隔符。呈现分隔符只要前后一致就可以了,但不能选择字母和 < 字符做为呈现分隔符。如果要在呈现方法中插入呈现字符就必须使用 \ 字符。
#  正确
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 替代字符串数组
在Ruby语言中到处充斥着语法糖衣,有很多的惯用表示法,对于初学者来说,往往被这些技巧 搞得晕头转向。 
这两天看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}完全一样,这边直接句个例子看结果:
  1. result = %{hello}  
  2. puts "result is: #{result}, Type is:#{result.class}"  
结果: result is: hello, Type is:String 

%Q{String}用于创建一个使用双引号括起来的字符串  
%q{String}用于创建一个使用单引号括起来的字符串  
从说明中可以看出这两个表示法的区别就是一个使用双引号,一个使用单引号。使用双引号的字符串会对字符串中的变量做较多替换,而单引号则做较少的替换,具 体看例子。先看%Q{String}: 

  1. world = "world"  
  2. result = %Q{hello #{world}}  
  3. puts "result is: #{result}, Type is:#{result.class}"  
结果: result is: hello world, Type is:String 

换成%q{String}: 

  1. world = "world"  
  2. result = %q{hello #{world}}  
  3. puts "result is: #{result}, Type is:#{result.class}"  
结果: 
result is: hello #{world}, Type is:String 

从上面的结果可以看出,较少替换的情况下,#{world}被解析成了字符串,而不会去计算这个变量中的值。 

%r{String}用于创建一个正则表达式字面值  
就像使用/reg/方式一样,看代码: 

  1. result = %r{world}  
  2. puts result =~ "hello world"  
  3. puts "result is: #{result}, Type is:#{result.class}"  
结果: 6 
result is: (?-mix:world), Type is:Regexp 

可以看出,world从第6个字符开始匹配 

%w{String}用于将一个字符串以空白字符切分成一个字符串数组,进行较少替换  
%W{String}用于将一个字符串以空白字符切分成一个字符串数组,进行较多替换  
这两个应该是大家见过最多的,用这个方式构造数组,可以省下一些逗号,Ruby真 是会惯坏大家,以后大家都不用标点符号了。 
同样给一个简单的例子: 

  1. result = %w{hello world}  
  2. puts "result is: #{result}, Type is:#{result.class}, length is:#{result.length}"  
结果: result is: helloworld, Type is:Array, length is:2 

%s{String}用于生成一个符号对象  
直接先上代码: 
  1. result = %s{hello world}  
  2. puts "result is: #{result}, Type is:#{result.class}"  
  3. sym = :"hello world"  
  4. 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下的记事本,这里我就不列结果了(那是一个大家熟悉的窗口)。

 

ruby文件读写的好文章 ruby way之IO之一

原:http://blog.csdn.net/passionboyxie/article/details/7377717
http://simohayha.javaeye.com/blog/153398
1 打开和关闭一个文件 
类方法File.new 打开一个文件,并将它实例化为一个File对象,他的第一个参数是文件名. 
可选的第二个参数叫做 mode string(这个也是从c得来的).他的意思是怎样打开一个文件(读,写或者其他的).默认是'r'(也就是读). 
Ruby代码
  1. file1 = File.new("one")       # Open for reading  
  2.   
  3. file2 = File.new("two","w")  # Open for writing  
[ruby]  view plain copy
  1. file1 = File.new("one")       # Open for reading  file2 = File.new("two", "w")  # Open for writing  
另外一种new的形式是三个参数的,其中第二个参数是指定了这个文件的原始的权限(经常表示为一个八进制的数).第三个参数是一系列Ored标志 的组合.标志是个常量比如File:CREAT(如果文件不存在则创建它)和File:RDONLY(以只读方式打开文件)。不过这种形式很少使用:

Ruby代码
  1. file = File.new("three", 0755,File::CREAT|File::WRONLY)  
[ruby]  view plain copy
  1. file = File.new("three", 0755, File::CREAT|File::WRONLY)  


出于对操作系统和运行环境的考虑,如果你打开了一个文件的话,你就必须关闭它。当你打开一个文件用于写时,你更应该这样做,从而才能免于丢失数据.close方法就是关闭一个文件:

Ruby代码
  1. out = File.new("captains.log","w")  
  2. # Process as needed...  
  3. out.close  
[ruby]  view plain copy
  1. out = File.new("captains.log""w"# Process as needed... out.close  

这里还有一个open方法,它的最简单的形式是和new同义的: 
Ruby代码
  1. trans = File.open("transactions","w")  
[ruby]  view plain copy
  1. trans = File.open("transactions","w")  


但是open方法还能够带一个block作为参数,当存在block时,打开的文件将会做为一个参数传递给block.这时这个文件将会在这个block的作用域里,保持打开,直到block结束时,自动关闭:

Ruby代码
  1. File.open("somefile","w")do |file|  
  2.    file.puts "Line 1"  
  3.    file.puts "Line 2"  
  4.    file.puts "Third and final line"  
  5. end  
[ruby]  view plain copy
  1. File.open("somefile","w"do |file|   file.puts "Line 1"   file.puts "Line 2"   file.puts "Third and final line" end  


2 更新文件 

假设我们想要打开一个文件用于读和写,简单的加一个'+'号到file mode就行了: 
Ruby代码
  1. f1 = File.new("file1","r+")  
  2. # Read/write, starting at beginning of file.  
  3. f2 = File.new("file2","w+")  
  4. # Read/write; truncate existing file or create a new one.  
  5. f3 = File.new("file3","a+")  
  6. # Read/write; start at end of existing file or create a  
  7. # new one.  
[ruby]  view plain copy
  1. 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就行了: 

Ruby代码
  1. logfile = File.open("captains_log","a")  
  2. # Add a line at the end, then close.  
  3. logfile.puts "Stardate 47824.1: Our show has been canceled."  
  4. logfile.close  
[ruby]  view plain copy
  1. 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):
Ruby代码
  1. # myfile contains only: abcdefghi  
  2. file = File.new("myfile")  
  3. file.seek(5)  
  4. str = file.gets                   # "fghi"  
[ruby]  view plain copy
  1. # myfile contains only: abcdefghi file = File.new("myfile") file.seek(5) str = file.gets                   # "fghi"  


如果你能确定每一行都是固定的长度,你就能seek指定的行: 
Ruby代码
  1. # Assume 20 bytes per line.  
  2. # Line N starts at byte (N-1)*20  
  3. file = File.new("fixedlines")  
  4. file.seek(5*20)                   # Sixth line!  
  5. # Elegance is left as an exercise.  
[ruby]  view plain copy
  1. # 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.  
如果你想做一个相对的搜索,你就要使用第二个参数,常量 IO::SEEK_CUR表示当前的位置,而第一个参数则就是相对于当前位置的偏移量(可能是负数):

Ruby代码
  1. file = File.new("somefile")  
  2. file.seek(55)                 # Position is 55  
  3. file.seek(-22, IO::SEEK_CUR)  # Position is 33  
  4. file.seek(47, IO::SEEK_CUR)   # Position is 80  
[ruby]  view plain copy
  1. 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  


你也能从文件的结束位置开始搜索: 

Ruby代码
  1. file.seek(-20, IO::SEEK_END)  # twenty bytes from eof  
[ruby]  view plain copy
  1. file.seek(-20, IO::SEEK_END)  # twenty bytes from eof  
方法tell得到文件的当前位置,pos是它的别名: 

Ruby代码
  1. file.seek(20)  
  2. pos1 = file.tell             # 20  
  3. file.seek(50, IO::SEEK_CUR)  
  4. pos2 = file.pos              # 70  
[ruby]  view plain copy
  1. file.seek(20) pos1 = file.tell             # 20 file.seek(50, IO::SEEK_CUR) pos2 = file.pos              # 70  
rewind方法将会将文件指针的位置设回到开始的位置,也就是0. 

5 操作二进制文件 

在很久以前,c语言通过在file mode后附加一个'b'来表示将文件用二进制模式打开.在今天,二进制文件的处理已经没有那么麻烦了。在ruby中,一个字符串很容易保存一个二进制数据,而且也不用通过任何特殊的方式来读文件.

可是在windows下是例外,在他下面,二进制文件和文本文件的不同是,在二进制mode下,结束行不能被转义为一个单独的换行,而是被保存为一个回车换行对. 
另外的不同是,在文本模式下 control-Z被作为文件的结束: 

Ruby代码
  1. # Create a file (in binary mode)  
  2. File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") }  
  3. # Above note the embedded octal 032 (^Z)  
  4. # Read it as binary  
  5. str = nil  
  6.   
  7. File.open("myfile","rb") {|f| str = f.sysread(15) }  
  8. puts str.size           # 11  
  9. # Read it as text  
  10. str = nil  
  11. File.open("myfile","r") {|f| str = f.sysread(15) }  
  12. puts str.size           # 5  
[ruby]  view plain copy
  1. # 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  
这边注意,这些代码都是在windows下才会打印出后面的结果,如果是在linux两处都会打印出11. 
再看下面的代码: 
Ruby代码
  1. # Input file contains a single line: Line 1.  
  2. file = File.open("data")  
  3. line = file.readline             # "Line 1.\n"  
  4. puts "#{line.size} characters."   # 8 characters  
  5. file.close  
  6. file = File.open("data","rb")  
  7. line = file.readline             # "Line 1.\r\n"  
  8. puts "#{line.size} characters."   # 9 characters 二进制模式的结尾是一个回车换行对.  
  9. file.close  
[ruby]  view plain copy
  1. # 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  
binmode方法能够转换当前的流为二进制模式,这边要注意的是,一旦切换过去,就不能切换回来了: 
Ruby代码
  1. file = File.open("data")  
  2. file.binmode  
  3. line = file.readline             # "Line 1.\r\n"  
  4. puts "#{line.size} characters."   # 9 characters  
  5. file.close  
[ruby]  view plain copy
  1. file = File.open("data") file.binmode line = file.readline             # "Line 1.\r\n" puts "#{line.size} characters."  # 9 characters file.close  
如果你想使用更底层的输入输出,那你可以选择sysread和syswrite方法,他们接受一定数量的字节作为参数 . 
Ruby代码
  1. input = File.new("myfile",'a+')  
  2. output = File.new("outfile",'a+')  
  3. instr = input.sysread(10);  
  4. puts instr  
  5. bytes = output.syswrite("This is a test.")  
[ruby]  view plain copy
  1. 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

代码如下

下载:  delline.rb
  1. ifARGV.length<2then
  2.   puts "USAGE: ruby delline.rb text_file_name str1 [str2 ...]"
  3.   exit
  4. end
  5.  
  6. i_file_name = ARGV[0]
  7. i_file_name_bak = i_file_name +".bak"
  8. if FileTest.exist?(i_file_name)then
  9.   File.rename(i_file_name,i_file_name_bak)
  10. else
  11.   puts "File #{i_file_name} was not found"
  12.   exit
  13. end
  14.  
  15. i_file = File.new(i_file_name_bak,"r")
  16. o_file = File.new(i_file_name,"w")
  17.  
  18. i_file.each_line do |line|
  19.   delete_flag =true
  20.   1.upto(ARGV.length - 1) do |x|
  21.     if !line.include?(ARGV[x]) then
  22.       delete_flag =false
  23.       break
  24.     end
  25.   end
  26.   o_file.puts lineif !delete_flag
  27. end
  28.  
  29. i_file.close
  30. 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" 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值