版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Ruby技巧Ruby技巧001常值所谓常值(literal),就是用来将数值、字符串等基本的对象直接写在脚本中的表示法。数值
数值时在程序中可被处理的一种最基本的数据形态。
数值在处理中,与整数及小数有着很大的差异。另外,如果使用标准内建的函数库,也可以处理矩阵、复数等整数、浮点数以外的其他数据形态。
数值常数包括整数与浮点数。
整数
1
-1
1000000000000000
整数包括固定长整数(Fixnum)与大数(Bignum)。Fixnum可表示系统平台上自然操作的数值范围(对32位机器是-230~230-1),而Bignum则表示比此范围更大的整数。因为这两种整数会视需求自动变换,所以一般在编写Ruby的脚本时,不需要特别去区分。
在整数中,可以依据个人喜好在每位数中间加入“_”。在描述位数较多的数时,可以更容易阅读。
1_000_000_000
另外,整数不仅可以表示十进制数,也可以表示二进制数、八进制数、十六进制数。
sample001-01.rb
#以“0b”开头的为二进制数
bin_num=0b01101101
pbin_num
#=>109
#以“0”开头的为八进制数
oct_num=0751
poct_num
#=>469
#以“0x”开头的为十六进制数
hex_num=0xAF83
phex_num
#=>44931
浮点数
浮点数是指使用浮动小数点表示的数。浮动小数点分为“假数部分”与“指数部分”,以“假数X10指数部分”来表示。如此一来,由大的数值到小的数值,都可以用限制的位数来处理。
在Ruby中,指数部分与假数部分是以“假数e指数”的形式来表示。例如:1.4*100000会以“1.4e5”来表示,2.0/1000会以“2.0e-3”来表示。
1.2
1.4e5
#1.4X(10的5次方)
2.0e-3
#2.0X(10的-3次方)符号
符号用来表示方法名等,对应内部所使用值的对象。符号是以“:”起始的英文与数字所构成(开头的字符不可使用数字)。
:sym
:s001
在Ruby1.8中,新增了符号的写法。
:"symbol123"
#符号“symbol123”
%s[symbol123]
#符号“symbol123”
在过去包含空格符的符号是不可以使用的,但通过新增的写法,前面那些包含空格符等的符号,也可以使用了。字符串
字符串处理是Ruby拿手的领域之一。为此,在字符串的表示上,导入了如下各种的写法。
"RubyOnRails学习网"
%q[中国北京]
%Q(ROR学习网)
<<"ROR"
红宝石比珍珠好
HELLO
“''”与“""”这两种将字符串包住的写法与其他程序语言是相同的。“''”与“""”的差异有以下两点。
“""”可使用特殊字符
“""”可在其中展开“#{表达式}”的具体描述语句
所谓特殊字符是指如\n、\t这样附有“\”的字符。\n表示换行,而\t表示跳格。另外,还有像\x5a这样的形式是可以用字符的十六进制数来表示的写法。
表达式展开是将Ruby的表达式嵌入字符串中的一种写法。若在“""”的字符串中有“#{表达式}”这样的字符串,则会执行其中的表达式,并将其结果在字符串中取代“#{表达式}”。
最后,我们使用“<<”的三行写法,称为HereDocument。HereDocument将在“<<”的下一行起,一直到某一行开头为前面第一行中“<<”后所接字符串的行为止的所有文字作为一个字符串。
在HereDocument中也可以展开表达式。正则表达式
正则表达式是一种用来表示字符串样式(pattern)的写法,使用在与字符串的比对上。
正则表达式的写法有两种:以“//”包住的写法与以“%r”开头的写法。
在使用以“//”包住的写法时,样式中不可以直接写入“\”。我们必须透过“\”来跳脱(Escape)。
/R.*y/
#可相配“R”之后出现任意字符0次以上之后接“y”的字符串
/Ruby\/Python/
#可相配“Ruby/Python”字符串
例如:与“/rubybase/”及“/rubycase/”相配的正则表达式可以用下面的写法表示。使用“%r”的时候,在“%r”的下一字符表示常值的起始于结束。
%r|http://www\.5iror\.com/rubybase/|
%r!http://www\.5iror\.com/rubycase/!
当“%r”的下一个字符是“(”、“[”、“{”、“<”的时候,所对应字符的一对表是常值的起始与结束。
%r[R.*y]
%r{http://www\.5iror\.com/rubybase/index\.htm}
在正则表达式中有“/”字符时,使用“%r”的方法比较方便。数组
数组的常值有使用“[]”来包住的写法以及“%w”的写法。如果使用“[]”,则以“,”区分开来的常值就会成为数组中的一个个元素。
[1,2,3]
如果使用“%w”,则以空格符来分开的常值会变为数组中的元素,如:
%w(abc)
在这种情况下,即使间隔两个以上的连续空格符,也只会区隔出一个元素。
p%w(ab
c)
#=>["a","b","c"]
如果以“%W”来取代“%w”的话,则可以进行表达式的展开。
p%W(ab#{1+1})
#=>["a","b',"2"]哈希(Hash)
哈希的写法使用“{}”,例如将键“a”对应值设为“b”、将键“c”对应值设为“d”的哈希,可以使用下列写法。
hash={"a"=>"b","c"="d"}
也可以使用“,”来替代“=>”。
hash={"a","b","c","d"}
在这种情况下,键与其对应值为一对一的映像,哈希中元素的数量必须为偶数。输出指令
要输出指令的写法可以使用“ˋˋ”(此处非单撇号(Singleapostrophe),而是反向撇号(Backapostrophe))。以“ˋˋ”括起来的字符串可以作为命令行指令来执行,而其结果会以输出字符串方式传回。
ˋechoRubyˋ
#执行echo指令
另外也可以使用“%x”的写法。
%x(echoRuby)
#执行echo指令
关于命令行指令的执行与输出,也请参考以后章节的“启动指令”。Ruby技巧002运算符Ruby的运算符有方法类的写法与非方法类的写法(与控制结构有关)。一元运算子
一元运算子就是像“!var”这样置于变量或表达式之前的运算符。
一元运算子除了有正负号之外,也有否定运算符及逻辑运算符。
否定
!
not
~(位反转)
正负号
+
-二项运算符
二项运算符是像“1+2”这样向左右两方获取对象来进行运算的运算符。
Ruby的运算符如表1-1所示。大多数都是二项运算符。虽然处理算术运算以及比较的运算符较多,但是也有一些如“1...10”这样用于产生范围对象的范围运算符。表1-1Ruby运算符优先顺位运算符对应的方法意义高
低
::
无
将类别与模块等连接
[]
[]
对数组存放
!
无
否定(优先度高)
~
~
按位作NOT运算(bitwise-not)
+(单项)
+@
正号
**
**
次方
-(单项)
-@
负号
*
*
乘法运算
/
/
除法运算
%
%
取余数
+
+
加法
-
-
减法
<<
<<
左移(位运算)
>>
>>
右移(位运算)
&
&
按位作AND运算(bitwise-and)
|
|
按位作OR运算(bitwise-or)
^
^
按位作XOR运算(bitwise-exclusive-or)
<
<
比小
>
>
比大
<=
<=
以下
>=
>=
以上
<=>
<=>
比较大小(航天飞机运算符)
==
==
同值判断
!=
==的否定
“==”的否定(即“不等于”)
=~
=~
用于正则表达式之比较
!~
=~的否定
“=~”的否定
===
===
在case语句中的同值判断
&&
无
逻辑积(优先度高)
||
无
逻辑和(优先度高)
..
无
产生Range对象(包含结尾)
...
无
产生Range对象(不包含结尾)
?:
无
条件运算符
=
无
代入值(包含+=、-=等)
not
无
否定(优先度低)
and
无
逻辑积(优先度低)
or
无
逻辑和(优先度低)
其他运算符
其他运算符还包括条件运算符、数组参考运算符。
条件运算符以
条件?表达式1:表达式2
的形式来使用,与以下if语句表达的意义相同。
if条件then
表达式1
else
表达式2
end
数组参考运算符[]在当我们要以索引存取如“var[0]”这样的数组对象时使用。无法以方法定义的运算符
下列运算符无法作为方法来定义:
::、..、...、?:(条件运算符)、not、and、or、!、&&、||、=Ruby技巧003变量与常数在Ruby中有5种类型的变量,另外还有常数。变量的种类是依变量的有效范围(scope)来分类的。到底是哪一种类型的变量或者是常数,我们可以依据其名称的开头字符来决定。局部变量
局部变量只能由方法、区块或者类别的定义语句来存取。其名称以小写英文字母或者“_”起始,由英文字母、数字与“_”组成,如:
1var实例(instance)变量
实例变量仅属于某个特定的对象,仅能由该对象中的方法来存取。其名称以“@”开头,由英文字母、数字及“_”组成,如:
@ivar类别变量
类别变量属于特定的类别,可由该类别与其子类别以及其实例(instance)来存取。其名称以“@@”开头,由英文字母、数字与“_”组成,如:
@@cvar全局变量
全局变量不论在程序中的任何一个地方都可以使用。其名称以“$”开头,由英文字母、数字与“_”组成,如:
$gvar虚拟变量
self、true、false、nil、_FILE_、_LINE_这些被称为虚拟变量。虽然虚拟变量称为“变量”,但其不可代入,几乎与常数没有差别。它会被称为“变量”,是因为其名称所使用的字符种类与局部变量相同。常数
常数是设置某定义后,其值就不会变更。其名称以答谢英文字母起始,由英文字母、数字及“_”组成,如:
ConstRuby技巧004代入
所谓的代入就是使用“=”,如:
a=3多重代入
如果我们使用下例中的写法,可以同时将1代入a,将4代入b,将9代入c。这种功能就称为多重代入。
a,b,c=1,4,9变量定义
一个变量会在其开始代入的同时被定义。如果参考到未被定义的参数就会产生错误。
punknown_var
#=>错误
不过,如果是代入值到变量的程序语句被写到程序中,这样即使实际上没有被代入值,此变量也会被定义。如:
iffalse
a=0
#此处并没有被实行
end
#但是,还是可以参考变量a,会变为nil
pa
#=>nil
虽然如此,但除非特别需要,不然的话还是在使用变量前先将值代入较好吧。Ruby技巧005程序语句的分段一般来说,在Ruby中以换行来作为程序语句的分段。
hello()
#一行程序语句
world()
#另一行程序语句
也可以使用“;”来明确地表示程序语句的分段。
hello();world()
这样的话,可以在一行中写入多行程序语句。
另外,在程序语句的最后有两项运算符,或者方法中的参数中有换行的情况等时,换行就无法作为程序语句的分段。如:
func1("a',"b",
#到此程序语句尚未结束
"c"+
#到此程序语句仍未结束
"d")
#至此func1方法的语句才算结束
上面这段脚本与“func1("a","b","c"+"d")”的程序语句是等价的。Ruby技巧006备注
如果我们要在Ruby脚本中加入一些非脚本的字符串时,就要使用备注的方式。
在Ruby脚本中,以“#”开头的行会被视为程序的备注。
#备注
obj.some_method()
#这边“#”后写的也是备注
另外,以“=begin”开头的行一直到以“=end”开头的行,其中间被包住的内容,会全部被视为备注来处理。
=begin
备注
备注
=endRuby技巧007真假值与条件判断真假值
下面说明的条件判断等内容,是以判断某个值为真或为假来做相应的处理。在Ruby中,仅有false与nil为“假”,除此之外的值都会被视为“真”来处理。条件判断
条件判断便是使用if语句、unless语句以及case语句(then可以省略)。
if条件then
我们想进行的处理
end
if条件then
处理1
else
处理2
end
if条件1then
处理1
elsif条件2then
处理2
elsif条件3then
处理3
else
处理4
end
unless条件then
我们想进行的处理
end
if与unless也可以写在执行处理部分的程序语句后。在这种情况下,if与unless又各自可称为if修饰词与unless修饰词。
我们想进行的处理
if条件
我们想进行的处理
unless条件
“我们想进行的处理”也可以通过begin~end包住多行程序语句的方式来书写,如:
begin
我们想进行的处理
endif条件
begin
我们想进行的处理
endunless条件
而case语句也可以采用如下的使用方式(then可以省略)。
case想比较的表达式
when值1then
处理1
when值2then
处理2
when值3then
处理3
else
处理4
end
想比较的表达式以==运算符(Object#==)与出现的值进行比较后,若与值1的比较为真,则进行处理1;与值2比较为真则进行处理2;与值3的比较为真则进行处理3,若与上列三个值的比较都不为真则进行处理4。无论进行了哪一个处理,处理完后就会跳出case语句。
从Ruby1.8版之后,也可以像下页用省略条件对象的方式来写case语句了。
case
when值1then
处理1
when值2then
处理2
when值3then
处理3
else
处理4
end
于是就会个别当值1为真时进行处理1这样合适的方式来执行。
此外,另一种条件判断的写法,可以使用“and”、“or”、“&&”、“||”。and与&&是当左边的部分为真时,便会执行右边的部分;or与||是当左边的部分为假时,会执行右边的部分。
程序语句and程序语句
程序语句or程序语句
程序语句&&程序语句
程序语句||程序语句
“&&”与“and”,以及“||”与“or”的优先级是不同的。详细说明请参阅“002运算符”中的说明。Ruby技巧008循环循环语句与条件判断语句相似。但与条件判断语句不同的是循环语句是到满足条件为止,会进行多次的循环处理(do可以省略)。
while条件do
我们想进行重复循环的处理
end
until条件do
我们想进行重复循环的处理
end
for变量in对象do
我们想进行重复循环的处理
end
当我们想进行循环的语句只有一行的时候,使用while修饰词与until修饰词就很方便了。
希望进行循环的处理while条件
希望进行循环的处理until条件
在循环中的语句最少会执行一次,也就是在第一次的条件判断前,就执行循环中的语句,这样情况可以使用“begin希望进行循环的处理endwhile条件”的形式来进行循环控制。
begin
希望进行循环的处理
endwhile条件
begin
希望进行循环的处理
enduntil条件
另外,使用下列指令可以在循环执行的过程中中断循环,也可以回到循环开头重新执行,如表1-2所示。表1-2中断循环的命令命
令内容break强制中断循环next前进到下一次的循环执行retry重新开始循环执行redo以相同的条件再执行一次循环Ruby技巧009调用方法调用方法
调用方法如下例的方式:
对象.方法名(方法的参数)
没有参数或者所有的参数要设置为系统默认的时候,方法的参数可以省略。方法的参数的“()”在不需要特别说明的情况下也可以省略。
例如:要调用STDOUT对象的puts方法时可以如下面这样写:
STDOUT.puts("ruby")
STDOUT.puts"ruby"
#省略“()”的情况
参数中,可以将数组以“*”展开后传入。
a=[1,2,3]
obj.some(*a)
#obj.some(1,2,3)
另外,调用方法对象的对象称为receiver。
调用函数形式的方法
调用函数形式的方法方式如下:
方法名(方法的参数)
在这种情况下,self担任了receiver的角色。关于self,请参阅[011]“方法定义”与[013]“类别定义”。
例如,调用函数形式的方法puts,可以使用下列方式:
puts("ruby")Ruby技巧010区块(block)在Ruby的方法中可以传入区块。
对象.方法名do|区块参数|
区块定义主体
end
也可是使用“{~}”来代替“do~end”。
对象.方法名{|区块参数|
区块定义主体
}
也可以将参数加入到方法中。
对象.方法名(方法的参数)do|区块参数|
区块定义主体
end
区块参数用来进行方法定义与区块定义主体间的信息交换操作。在带有区块的方法定义中,一旦区块被调用,可将值代入区块参数,而区块定义主体则会被执行。
下例中所使用的Integer#times是只将receiver的数进行循环的一个方法。区块参数会依次被代入0、1、2、3、4,然后执行print方法将其输出。
5.times{|i|
printi
}
#=>01234Ruby技巧011方法(Method)定义使用def语句可以定义方法。
def方法名(参数列表)
方法定义
end
方法定义会在执行时被Ruby解析。
参数列表的四种参数仅能以下列的顺序来定义。
param
一般的参数(0个以上)
param=val
附有默认值的参数(0个以上)
*param
长度可变的参数(0~1个)
¶m
将区块Proc化后接收的参数(0~1个)
一个使用所有类型参数的方法定义如下:
defsample_method(name,value,dvalue="sample",*rest,&block)
name与value为一般的参数;dvalue为附有默认值的参数;*rest为长度可变的参数,而&block为被区块Proc化后接收的参数。
附带区块的方法定义
在附带有区块的方法定义的情况下,执行被传递给方法的区块时,使用yield。yield会将接收到的参数作为区块参数传递给区块。
defmap_with_index(list)
result=[]
list.each_with_index{|item,idx|
value=yield[item,idx]
result<<value
}
returnresult
end
map_with_index([1,2,3]){|item,idx|item*idx}
#=>[0,2,6]Ruby技巧012限制方法的调用限制方法的调用有以下3种方式:
public
将方法定义为可由其他类别定义或者最上层来调用。
private
只能以省略receiver的形式来调用方法。
protected
只能在与方法的同一个类别或其子类别中调用该方法。
当没有特别指定的时候会预设为public。但是initialize方法除外,initialize方法一般都是private。
在绝大多数情况下,只会使用public与private。当我们希望在该类别外也可以存取该方法时使用public,不希望时则使用private。Ruby技巧013类别(Class)定义要定义一个类别时,使用class语句。
class类别名
类别的定义
end
也可以定义一个继承其他类别的子类别。
class子类别(subclass)名<父类别(superclass)名
类别的定义
end
类别也可以使用巢状结构。
classC1
classC2
:略
end
end
c=c1::c2.new
在Ruby1.8版以后,可以在类别名称上使用“::”来直接指定巢状结构中深一层的类别。不过被写入巢状结构的类别一定要事先定义好才可以使用。
classC1
:略
end
classC1::C2
deffoo
p"foo"
end
end
C1::C2.new.foo
#=>"foo"
在类别的定义中,self指的是该类别本身。在该类别的实例中,self指的是该实例本身。
classC1
p[self,self.class]
#=>[C1,Class]
deffoo
&nbp;
p[self,self.class]
end
end
C1.new.foo
#=>[#<C1:0x80fea64,C1]Ruby技巧014模块(Module)定义
在模块的定义要使用module语句。
module模块名
模块定义
end
虽然模块与类别类似,但其仍有若干差异。模块与类别的差别如表1-3所示。表1-3模块与类别的差别
类别模块引入不可可继承可不可建立实例(instance)可不可
要引入模块时应使用include语句。
moduleM1
end
classC
includeM1
#在类别C中引入模块M1
end
模块与类别一样,也可以对模块使用巢状结构,同时类别与模块交杂地使用巢状结构。
moduleM1
moduleM2
classC1
end
end
end
c=M1::M2::C1.new
模块的定义与类别相同,self是指该模块对象自身。当该模块被其他类别引入时,在模块的方法定义中的self则是指引入该模块的类别对象本身。Ruby技巧015特殊方法在Ruby中,不仅可以对类别或者模块定义方法。对于个别的对象,也可以定义该对象仅有的方法。这样定义的方法称为特殊方法。
def对象.特殊方法名(参数列表)
特殊方法的定义
end
此外,想要一次定义多数个特殊方法时,可以写成如下形式:
class<<对象
def特殊方法名(参数列表)
特殊方法的定义
end
end
这边的“class<<对象~end”形式称为特殊类别定义,而被这样定义的类别则称为“特殊类别”。参考特殊类别定义中的self可以存取特殊类别自身。Ruby技巧016例外处理
Ruby语言也支持例外处理。例如在读取文件失败的时候会产生例外,而Ruby便可抓取这样的例外,并进行相应的处理。
begin
主处理1
rescue
例外类别1=>变量1then
例外处理1
rescue
例外类别2=>变量2then
例外处理2
:
:
rescue例外类别n=>变量nthen
例外类别3
else
主处理2
ensure
主处理3
end
主处理1是进行可能会发生例外的处理。如果在此处发生例外的话,会与rescue处制定的例外进行比较。如果发生的例外是指定的例外类别1或其子类别时,就会执行例外处理1。否则就会接着与例外类别2进行比较。接着到例外类别n会重复进行比较的动作。
在省略例外类别的情况下,StandardError类别会被使用。
当没有发生例外的时候,主处理2会被执行。而主处理3则是不论有没有发生例外,最后一定会被执行。
另外,也有rescue修饰词。使用rescue修饰词,我们可以很简洁地将例外处理写为:
主处理rescue例外处理
上面的例子在进行主处理中发生例外时,就会执行例外处理。但这种形式的写法无法指定rescue例外类别。Ruby技巧017alias与undef赋予别名
Ruby中的方法可以被赋予别名。要对方法赋予别名时使用alias语句。
alias别名原本的名称
例如要赋予method_old方法一个别名“method_new”时,可以像下面这样写:
aliasmethod_newmethod_old
方法名的指定别名也可以使用符号。
alias:method_new:method_old
将方法定义为不可使用
要将已经被定义的方法定义为不可使用时,可以使用undef语句。
undef方法名
例如要将some_method方法定义为不可使用时可以使用下列语句:
undefsome_method
undef:some_method
#这样也可以Ruby技巧018保留字Ruby中有一些名称不可以被用来当作变量名或者方法名称,这些名称叫做“保留字”。在实际使用中如果将这些名称拿来当作变量或者方法名称使用的话会发生错误。
Ruby的保留字如表1-4所示。表1-4Ruby的保留字
BEGIN
END
alias
and
begin
break
case
class
def
defined?
do
else
elsif
end
ensure
false
for
if
in
module
next
nil
not
or
redo
rescue
retry
return
self
super
then
true
undef
unless
when
while
yield
_FILE_
_LINE_
Ruby技巧019选择适当的字符串常值单引号的字符串“'”使用在字符串中不包含表达式展开时是很方便的。它是功能最少,且需要跳脱的字符只有“'”以及“\”。在字符串中,包含字符“\”或者包含字符“#”但不想进行表达式展开时使用相当方便。
p'question#{a}'
#=>"question#{a}"
%q
%q字符串在不包含表达式展开的字符串,而且也不包含“'”、“#”时使用相当方便。
p%q(在Ruby中写入#@ivar的话@ivar中的值会在字符串中被展开)
#=>"在ruby中写入#@ivar的话@ivar中的值会在字符串中被展开"
""
双引号字符串“""”是在字符串中包含表达式展开时用来表示字符串的首选。且本书在使用字符串常值时也会将双引号字符串当作首选。
p"doublequote#{1+1}string"
#=>"doublequote2string"
%Q
%Q字符串是使用在当字符串中含有表达式展开且有“"”的时候。例如将HTML的卷标作为字符串时使用时很方便的。
p%Q[<ahref="">5</a>]
#=>"<ahref=\"\">5</a>"
HereDocument
HereDocument在传递多行字符串时是很不错的选择。例如要嵌入HTML的标头、脚注以及原始码的一部分时使用。
p<<HEREDOC
这是HereDocument
这里也是HereDocument
HEREDOC
#=>"这是HereDocument\n这里也是HereDocument\n"
特别在原始码等常出现嵌入“\”的字符串时使用单引号HereDocument是最合适的。因为单引号HereDocument会将所有的跳脱字符视为无效。
#有“\”也没关系
module_eval(<<'End')
defprintln(arg)
printarg,"\n"
end
end
在处理多字节字符串时一定要先设置好$KCODE。在此范例中我们假设加载且执行$KCODE="UF8"(-Ku)。(译注:原文中是以处理日文的情况来设置的,而在此使用中文时,本教程预设使用UTF-8环境。)Ruby技巧020设置默认的文字编码
在进行字符串处理时,默认的文字编码是通过全局变量$KCODE来设置的。例如要设置为BIG-5时可以如下例:
$KCODE="NONE"
$KCODE可以设置为下列的值:
"EUC"
:EUC-JP
"SJIS"
:ShiftJIS
"UTF8"
:UTF-8
"NONE"
:无
在设置$KCODE值的时候,只有第一个字符是有意义的,而且英文大小写的差异会被忽略,所以$KCODE="EUC"也可以写作$KCODE="euc-jp"或者$KCODE="E"。但是相对于“e”或者“E”来说,“EUC”会是比较好理解的一种写法,所以我们建议各位尽可能地正确设置$KCODE的值。
另外在脚本中设置$KCODE的情况下,若没有先加载完毕再开始执行的话,是不会产生效果的。例如:在脚本中要直接写入文字编码为ShiftJIS的字符串时,虽然在脚本中写入了$KCODE="SJIS",但却在该字符串之后,这样便不会有更换文字编码的效果。在这种情况下,要在该字段脚本被读入之前先设置好$KCODE,不然就只能使用Ruby指令的-K参数。例如可以通过下列方式来设置:
>ruby-Ksscript.rb
关于-K参数的使用技巧,也请大家参考[024]“将Ruby脚本做成一般指令”。
另外若事先设置好环境变量RUBYOPT的话,Ruby会自动地设置好该参数。
#sh类的UNIXshell
RUBYOPT="-Ks"
exportRUBYOPT
#csh类的UNIXshell
setenvRUBYOPT-Ks
remWindows的命令提示字符(DOSprompt)
setRUBYOPT=-Ks
RUBYOPT的使用方法只有自己使用的话很方便,但是希望读者不要在发布出去的程序中强制设置RUBYOPT。Ruby技巧021变换文字编码JIS、EUC-JP、ShiftJIS、UTF8相互转换
要在JIS(iso-2022-jp)、EUC-JP、ShiftJIS及UTF8之间相互转换的话,使用nkf函数是最简单的方法。如果只有指定变换后的文字编码的话,则会自动推测变换前的文字编码,然后进行变换。例如下例可将big5码变换为UTF8码。
#第二参数中写入Big5码
require"nkf"
pNKF.nkf("-w-m0","\e$B8HAI>k304(;3;{\e(B\r\n")
#=>姑苏城外寒山寺
NKF.nkf的第一参数与nkf指令的选项相同。在文字编码变换时所使用的主要选项如表2-1所示。表2-1文字编码变换的主要选项
选
项
内
容
-j
变换为JIS(iso-2022-jp)
-e
变换为EUS-JP
-s
变换为ShiftJIS
-w
变换为UTF8
-J
将输入假定为JIS(iso-2022-jp)
-E
将输入假定为EUC-JP
-S
将输入假定为ShiftJIS
-W
将输入假定为UTF8
-x
将日文半角(JISX0201)直接留下,不变换。要变换为ECU-JP的时候使用SS0,变换为JIS时使用ESC
-X
将半角片假名(JISX0201)转换为全角片假名(JISX0208)
--cp932
编码页932,也就是与Windows中所用的文字编码(日文)进行互换。解决了与机种有关的文字以及部分记号无法正确转换的问题
译注:在繁体中文版的Windows中是使用950编码页,可将此932改为950。
在使用nkf方法的时候,误了要指定文字编码外,还应该要指定-m0选项。-m是指定将包含在邮件头等的MIME字符串进行译码的选项,不过很麻烦的是,这个选项默认是开启的。也就是说,只要偶然出现可以视为MIME字符串的话,其就会自动进行译码。所以我们在这里指定-m0来限制这样的功能。
将半角片假名转换为全角片假名的选项-X,其默认值也是开启的,所以如果想要保留半角片假名的话,就一定要随时加上-x选项。
变换更多种的文字编码
nkf函数在Ruby1.8.2版以后才可以处理UTF8,因此在Ruby1.8.1版之前要处理UTF-8的话,只能使用iconv函数。在处理JIS、EUC-JP、ShiftJIS、UTF-8以外的文字编码时都必须使用iconv函数。例如,我们将UTF-8的字符串utfstr转换为Big-5码:
putsIconv.conv("big5","UTF-8",utfstr)
Iconv.conv的第一个参数是变换后的文字编码,第二个参数是变换前的文字编码,这一点要请您特别注意。
iconv是使用系统的iconv函数,不过在有些系统中不存在iconv函数,而且支持的编码及其名称也是非常不规则。例如把“eucJP”换成“euc-jp”,在Solaris及Tru64UNIX5.1B中就会失败。在您的能力可以确认的范围内,使用下列的名称可以在大多数系统上运行。
"ISO-2022-JP"
"SJIS"
"eucJP"
"UTF-8"
译注:Big-5码的使用者可以使用“big5”或者“big-5”。
因为大小写的差别相当重要,所以请务必参照上例中的写法来编写。另外,在有些系统平台上,如果执行像“Iconv.conv("eucJp","eucJP",str)”这样变换前后编码都相同的话,便会出现错误。
我们在这里说明的是conv方法的参数中文字编码相同的名称,所以与变换表的兼容性事没有关系的。基本上,当系统不同的话,可以说变换表是没有兼容性的。
最后,虽然不是标准内建的函数,不过在UTF-8的变换上还可以使用uconv函数。uconv函数仅是以Ruby的扩充函数来完成的,所以在结果兼容性很重要的情况下,或许使用uconv会比较好。
Uconv.u8toeuc(str)
#UTF-8
->EUC-JP
Uconv.u8tosjis(str)
#UTF-8
->ShiftJIS
Uconv.euctou8(str)
#EUC-JP
->UTF-8
Uconv.sjistou8(str)
#UTF-8
->UTF-8
译注:uconv目前仅支持UTF-8、EUC-JP、JIS、ShiftJIS、CP932、UTF-16,尚未支持中文编码。
说明:在处理多字节字符串的时候,一定要事先设置$KCODE。在这项技巧中,我们假设的环境是设置$KCODE="UTF8"(-Ku)后,再进行加载、执行。
nkf函数只有在Ruby1.8.2版之后才支持UTF-8。
iconv函数是在Ruby1.8版之后为标准内部函数库。
要取得非标准内部函数库的话,可以由下列位置取得。
/list.rhtml?name=uconvRuby技巧022推测文字编码
要推测字符串的文字编码,可以使用nfk函数的NFK.guess。
require"nfk"
str="这是中文字符串"
NFK.guess(str)
guess方法会传回结果NFK::JIS、NFK::EUC等常数(数值)。想要通过文字编码名得到推测结果的话,可以如下例所示:
require"nkf"
CODE_TO_NAME=Hash.new("ASCII")
CODE_TO_NAME[NFK::JIS]
="JIS"
CODE_TO_NAME[NFK::EUC]
="EUC"
CODE_TO_NAME[NFK::SJIS]
="SJIS"
CODE_TO_NAME[NFK::BINARY]="BINARY"
CODE_TO_NAME[NFK::UTF8]
="UTF8"
ifNFK.const_defined?(:UTF8)
defguess_encoding(str)
CODE_TO_NAME[NFK.guess(str)]
end
因为原本就是“推测”的,所以guess方法也会有推测错误的情况。基本上,请大家要考虑到在脚本中不得不推测文字编码会发生错误的情况。
此外,NFK.guess方法如果不是Ruby1.8.2以后的版本,则没有办法推测UTF-8编码。在Ruby1.8.1之前要推测字符串编码是否为UTF-8的话,要通过iconv函数将字符串变换到目的字符串编码。
sample022-03.rb
require"iconv"
require"nfk"
defguess_encoding2(str)
Iconv.iconv("UTF-8","UTF-8",str)
"UTF8"
rescueIconv::Error
guess_encoding(str)
#UTF-8以外利用nfk来推测
endRuby技巧023复制字符串
要复制字符串的话,可以利用String#dup或String#clone。
str="Thisisastring"
pstr.dup
#=>"Thisisastring"
pstr.clone
#=>"Thisisastring"
pstr.object_id
#=>538155386
pstr.dup.object_id#=>538155366
dup方法只会复制字符串的内容。clone除了复制字符串的内容,同时也继承了特殊方法、污染(taint)、冻结(freeze)等信息。
一般来说,使用dup方法已经足够了。Ruby技巧024重复字符串
若要建立一个重复某个字符串的字符串,可以使用运算符“*”(String#*)。
p"foo"*5
#=>"foofoofoofoofoo"
p
"郁"*3
#=>"郁郁郁"
另外,数值的“*”运算符放在左边或者右边其结果都是相同的,但是在字符串中就不可以左右交换来放。一定要字符串放在运算符的左边,整数放在运算符的右边。反过来的话,就会发生像下例中的例外。
p5*"foo"
#=>TypeError:Stringcan'tbecoercedintoFixnum
说明:处理多字节字符串时必须要事先设置#KCODE。在此例中使用中文,就无须特别加上$KCODE的设置,但若是处理如UTF-8的字符串时,就必须先设置如$KCODE="UTF8"。Ruby技巧025取得字符串长度
在说“字符串长度”时,一般有两个意义:字节(Byte)数与文字数。
取得位数
字符串的位数可以通过String#length或String#size来取得。这两个方法虽然名称不同,但是其操作是相同的。
p"Thisisastring.".length
#=>17
p"ThisisaString.".size
#=>17
取得文字数
字符串的文字数可以通过下列方式取得:
p"字符串长度".split(//).size
#=>5
“split(//)”是String#split的特殊用法,将字符串分割至字符串数组中。数出该数组的长度也就是文字的长度。不过如果没有事先适当地设置好$KCODE的话,split可能会无法顺利运作。
说明:在处理多字节字符串时,一定要事先设置$KCODE。在这项技巧中,我们假设的环境是设置$KCODE="UTF8"(-Ku)后,再进行加载、执行。Ruby技巧026查找字符串
查询是否含有样式(Pattern)
如果只要查询字符串中是否包含样式的时候,可以使用=~运算符(Regexp#=~)
#是否包含有空格符或者Tab?
p(/[\t]/=~"ac")
#=>1
p(/[\t]/=~"abc")
#=>nil
查询样式第一次出现的字节位置
如果想要知道指定样式第一次出现的字节位置的话,可以使用String#index
p"xxxabcabcabcxxx".index(/abc/)
#=>3
p"xxxabcabcabcxxx".index(".")
#=>nil
p"xxxxxx".index(".")
#=>3
查询样式最后出现的字节位置
如果想要知道指定样式最后一次出现的字节位置的话,可以使用String#rindex。
p"xxxabcabcabcxxx".rindex(/abc/)
#=>
9
p"xxxabcabcabcxxx".rindex(".")
#=>nil
p"xxxxxx".rindex(".")
#=>11
取得匹配的详细信息
使用Regexp#match的话,可以取得关于匹配的详细信息(MatchData对象)。我们可以由此对象中取得关于匹配部分的开头、结尾的字节位置,以及匹配部分的字符串等各种信息。String#match也可以取得与Regexp#match同样的结果。
m=/abc/.match("xxxabcabcabcxxx")
pm.begin(0)
#=>3
pm.end(0)
#=>6
pm[0]
#=>"abc"
pm.post_match
#=>"abcabcxxx"
m="xxxabcabcabcxxx".match(/abc/)
pm.begin(0)
#=>3
pm.end(0)
#=>6
pm[0]
#=>"abc"
pm.post_match
#=>"abcabcxxx"
在一个字符串中匹配所有的候选
到目前为止介绍的方法都只能匹配到在字符串中数个可匹配的开头(或者结尾)部分的其中一个,不过实际上我们也可以让程序去匹配所有符合的部分。这就要使用String#scan方法。
#匹配所有注音符号
str="ㄅ\naadㄆㄇe\neㄈ0\n0aㄍ\niiㄚ\n"
str.scan(/[ㄅ-ㄜ]+/){|s|
putss
}
#=>ㄅ
#=>ㄆㄇ
#=>ㄈ
#=>ㄍ
#=>ㄚ
String#scan在正则表达式中加入“()”的话,则会改变其动作,请读者要注意。
只处理包含有样式的行
在一个字符串中包含多行的时候,若要重复处理包含样式的行,则可以使用String#grep(Enumerable#grep)。
#只处理包含有“快”或“乐”的行
str="快\naad好吃e\ne
乐0\n0a哈\nii好\n"
str.grep([快乐]){|line|
pline
}
#=>"快\n"
#=>"e乐0\n"
也就是说,下面两个方式是一样的。
str.gerp(re){|line|
各行的处理
}
str.each{
ifre=~line
各行的处理
end
}
说明:Ruby1.6版中String#scan的参数在两个以上字符串的情况下,会变换为Regexp对象之后进行查找,而在Ruby1.8版之后就会直接以该字符串来进行搜索。因此在有Meta字符(“.”及“*”等)的情况下,其运作会有所不同。要避开这个规格的问题,只要一直都使用正则表达式的参数就可以解决。
String#match在Ruby1.8版之后才被定义。
在处理多字节字符串的时候,一定要实现设置$KCODE。在这项技巧下,我们假设的环境是设置$KCODE="UTF8"(-Ku)后,再进行加载、执行。Ruby技巧027查询正则表达式是否匹配字符串的开头/结尾Ruby的正则表达式是以\A表示“字符串开头”,以\z(小写的z,请注意)表示“字符串结尾”。
p(/\A5/=~"5iror")
#=>0
p(/\Ao/=~"5iror")
#=>nil
p(/r\z/=~"5iror")
#=>4
p(/5\z/=~"5iror")
#=>nil
虽然一般我们看到匹配“字符串开头”、“字符串结尾”大多使用“^”、“$”,不过这也是有点差异的。因为“^”是指“行的开头”,而不是“字符串的开头”。“$”是指“行尾”,而不是“字符串的结尾”。而且使用大写Z的“\Z”是“字符串中的最后行尾”。
p"abc\ndef\nghi\n".slice(/..s/m)
#=>"bc"
p"abc\ndef\nghi\n".slice(/..\Z/m)
#=>"hi"
p"abc\ndef\nghi\n".slice(/..\z/m)
#=>"i\n"
只有在使用sub方法的时候,匹配“字符串开头”与“字符串结尾”才使用“^”与“$”,这与使用gsub方法并不相同。请明确区别。
说明:在处理多字节字符串的时候,一定要事先设置$KCODE。在这项技巧中,我们假设的环境是设置$KCODE="UTF8"(-Ku)后,才进行加载、执行。Ruby技巧028匹配单字
查询是否包含单字
首先,我们考虑当查询是否包含特殊单字的情况。例如我们想要查找“spec”,但不希望匹配到“specification”。在这种情况下,可以使用表示单字边界的正则表达式\b。
p/\bspec\b/=~"Rubyspec"
#=>5
p/\bspec\b/=~"Rubyspecification"
#=>nil
严谨地说,正则表达式的\b是匹配到\w(一个英文字母或数字)与\W(不与\w匹配的一个字符)的间隙。
不过,将$KCODE设置为"UTF8"的话,UTF-8的中文字也可以匹配\w,所以\b就变得无法匹配中文与英文字母的间隙了。
p/红宝石\b/=~"红宝石abc"
#=>nil
这好像是理所当然,不过又有点背离常理。
根据正则表达式引擎,可以使用表示“单字的开始”、“单字的结尾”的“\<”及“\>”,但是这两样不存在于Ruby的正则表达式引擎中。以前原本是存在的,不过后来因为“记号如果以\来跳脱的话,就会匹配到字符本身”的理由,在统一基准之前就被删掉了。
匹配单字
接着,我们来考虑匹配一般的“单字”。因为“单字”的意义并不一定,所以请读者先想看看,想要怎样的“单字”。例如说像下面的定义范例。
(1)匹配Ruby的正则表达式\w的连续字符
->可以表示为/\w+/。
p"
Thisis\ta2pen.".scan(/w+/)
#=>["This","is","a","2pen"]
(2)连续的英文字母
->可以表示为/[a-z]+/i。
p"
Thisis\ta2pen.".scan(/[a-z]+/i)
#=>["This","is","a","pen"]
(3)连续的非空格字符。必须以半角空格符来切分。
->可以通过String#slipt(nil)来取得。
p"
Thisis\ta2pen".split(nil)
#=>["This","is","a","2pen."]
如果不只要匹配,还要取出匹配部分的字符串的话,可以通过正则表达式并使用String#slice或String#scan方法。详细内容请参考[042]“取出正则表达式匹配的部分”。
说明:在处理多字节字符串的时候,一定要事先设置$KCODE。在这项技巧中,我们假设的环境是设置$KCODE="UTF8"(-Ku)后,再进行加载、执行。Ruby技巧029以特定的文字编码来进行正则表达式匹配
要处理多字节字符串时,设置$KCODE是基本工作,不过根据状况的不同,有时也无法设置$KCODE。比如说,在应用程序中设置$KCODE="NONE"时,我们只想要以函数中的一部分来处理UTF-8字符串。
在这种情况下,我们要在正则表达式中加入文字编码选项来进行处理。加上文字编码选项后,就与$KCODE无关,可以以同一个文字编码来进行正则表达式的匹配,如下面的脚本所示:
#正则表达式与字符串时通过BIG-5来输入的($KCODE="NONE")
p(/梣/
=~"博硕")
#=>0
p(/梣/n=~"博硕")
#=>nil
BIG-5的“梣”为"\325\272",而“博硕”为"\345\215\232\347\242\251",所以在没有设置$KCODE及文字编码的情况下,正则表达式会在不正确的位置匹配到字符串。但是后者的编码加上文字编码,可以清楚知道多字节文字的区分处,所以可以正确地判断匹配的失败。
目前,可以使用的文字编码有下列四种,如表2-2所示。其与$KCODE的第一个字符相同,读者可以将其记下。表2-2文字编码
选
项
内
容
n
无法处理多字节字符串
e
EUC-JP
s
ShiftJIS
u
UTF8
在处理多个文字编码的情况下,不要直接在脚本中写入EUC或者ShiftJIS的字符串常值比较好。例如ShiftJIS的“表”等如果不设置$KCODE="SJIS"的话是无法解析的,而如果设置$KCODE="SJIS"后,又可能会在其他的地方发生问题。此时使用跳脱字符的序列(EscapeSequence)来写入常值的话,就与$KCODE无关,而可以在正则表达式中嵌入多字节文字。
#BIG-5的“/程序语言/”
/#{"\265{\246\241\273y\250\245"}/n
#UTF8的“/程序语言/”
/#{"\347\250\213\345\274\217\350\252\236\350\250\200"}/u
在这种情况下,一定要使用表达式展开(#{表达式})。如果直接写上/\347\250\213\345\274\217\350\252\236\350\250\200/u,正则表达式的选项u就不会产生任何效果了。
注:本系列技巧的有关文字编码的问题均在处理UTF-8编码上,因为是原本Ruby就支持的文字编码,所以不会发生问题。而在处理中文的BIG-5编码上,因为Ruby本身并没有支持BIG-5编码的处理,所以在部分情况下会发生问题。
在目前来说,可能会使用到BIG-5编码的用户,大多数应该都是使用MicrosoftWindows操作系统的用户,就测试的结果而言,要在Windows操作系统上正确显示BIG-5编码的话,大多数的情况下无须特别设置$KCODE。但若发生无法正常显示变量内容,或者无法正常处理中文字符的情况下,可以试着将$KCODE设为"E"(EUC-JP),则可以正常处理。但此方法算是较困难的方法,且不保证在所有BIG-5码的处理中都可以正常运作。
就目前来说,要以Ruby来正常处理中文字符的话,建议大家采用UTF-8编码会是比较好的选择。Ruby技巧030在正则表达式“.”中匹配\n在正则表达式中加入m选项。
p(/./=~"\n")
#=>nil(因为没有m选项,所以.不会匹配\n)
p(/./m=~"\n")
#=>0(加上m选项,所以.可以匹配\n)
加上m选项之后,“.”可以匹配任何字符。
对应多字节文字时的正则表达式“.”
在对应多字节文字为有效的时候,必须要特别注意。在文字中间切开的多字节文字,无论如何都无法与“.”匹配。
p(/./u
=~"博"[0,1])
#=>nil
p(/./um=~"博"[0,1])
#=>nil
而反过来说,在$KCODE="NONE"(或者加上n选项)中加入m选项的话,“.”就可以匹配到所有的字符。
defmatch_all_char?(re)
(0..255).map{|byte|byte.chr}.all?{|ch|re=~ch}
end
pmatch_all_char?(/./)
#=>false
pmatch_all_char?(/./um)
#=>false
pmatch_all_char?(/./nm)
#=>trueRuby技巧031从上次匹配的部分开始继续匹配
在进行过一次正则表达式匹配后,要在匹配的部分后面继续匹配的话,只要将已经匹配的部分字符串删除就可以了。我们可以通过$'或MatchData#post_match来取得“匹配部分之后”的字符串。
str="abcdefghijkl"
pstr.slice(/\w+/)
#=>"abc"
str=$'
pstr
#=>
#=>"defghijkl"
pstr.slice(/\w+/)
#=>"def"
若使用循环的话,就如同下例所示。
str="abcdefghijkl"
result=[]
whiletoken=str.slice(/\w+/)
result.pushtoken
str=$'
end
presult
#=>["abc","def","ghi","jkl"]
strscan函数就好像是为了“从上次匹配的部分之后继续进行匹配”而特制的函数。请看下面的例子。
require"strscan"
scanner=StringScanner.new("abcdefghijkl")
result=[]
untilscanner.eos?
result.pushscanner.scan(/\w+/)
end
presult
#=>["abc","","def","","ghi","","jkl"]
您可以将StringScanner#scan想成一个例子中同时进行slice与str=$'的一个方法。与string#slice和$'的使用场合的不同在于,这个方法只会匹配字符串的开头。因此我们必须要在正则表达式上加\W+(一个以上\w以外的字符),使其可以顺利地scan下去。
最后,我们在此简单说明StringScanner类别与其他方法。StringScanner#getch会传回开头的头一个文字(反映$KCODE)。Stringcanner#eos?会扫描到字符串结尾为止,若到字符串结尾则传回true。
StringScanner类别中还有其他许多的方法,不过因为在此无法完全写入,所以其他的详细内容还请大家参阅其参考手册。Ruby技巧032匹配单字
计算文字出现的次数
要计算特定文字在一个字符串中出现的次数可以使用String#count方法,不过这个方法并不支持多字节文字。
p"a\nb\nccc\nd\n".count("\n")
#=>4
计算多字节文字出现的次数
要计算特定的多字节文字在一个字符串中出现的次数可以使用String#scan方法。以scan方法来建立一个只含有匹配样式文字的数组,然后再以Array#length来求得数组的大小,也就是该文字出现的次数了。
#计算“博”“文”出现次数的总和
p"博博博博文文文博文视点".scan(/[博文]/).length
#=>9
当对象字符串大小接近无穷大的时候,通过scan方法来建立数组的成本会出现问题,可以使用下列方法不建立中间数组也可以计算。
count=0
"博博博博文文文博文视点".scan(/[博文]/){
count+=1
}
pcount#=>9
计算字符串的出现次数
如果我们不是要计算文字数而是要计算字符串的出现次数的话,也是使用String#scan。这个方法可以支持多字节字符串。
p"博博博博文文文博文视点".scan(/博文/).length
#=>2
说明:如果不想建立中间数组的话,可以如上所示使用区块的方式来计算。
在处理多字节字符串的时候,一定要事先设置$KCODE。在这项技巧中,我们假设的环境是设置$KCODE="UTF8"(-Ku)后,再进行加载、执行。Ruby技巧033计算字符的出现频率
使用下列方法,可以计算出在一个字符串str中各个字符出现的频率。
def
char_stat(str)
table=Hash.new(0)
str.scan(/./m){|ch|
table[ch]+=1
}
table.to_a.sort_by{|char,count|-count}
end
这个方法可以计算各个字符在字符串中出现的次数,然后将结果以从多到少的顺序传回。传回值为“[字符,出现次数]”这样的数组。使用方法参考下例。
char_stat("3.14159265357919").each{|char,count|
puts"#{char.inspect}:#{count}"
}
如下例的作法,可以算出各个字符在字符串中所占的比例。
str="3.14159265357919"
char_stat(str).each{|char,count|
puts"#{char.inspect}:#{count*100/str.length}%"
}
试着以这个方法来处理所遇Ruby1.8的标准函数文件的话,可以得到的前几名如下所示:
"":22%
"e":7%
"t":4%Ruby技巧034比较字符串
如果只是想要比较内容知道其内容是否相等的话,使用“==”是比较恰当的。
p"小青蛙"=="小青蛙"
#=>true
p"小青蛙"=="蛙"
#=>false
若不区分英文大小写来进行比较的话,可以将两字符串都以String#downcase变为小写后,再以“==”进行比较。
p"Content".downcase=="CONTENT".downcase
#=>true
如果想要以文字编码顺序来知道哪一个编码值较小的话,可以在字符串间使用比较运算符<、<=、>、>=等进行比较。
p"abc">"xyz"
#=>false
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 新冠隔离病区工作制度
- 新消毒供应室工作制度
- 新闻发布报备工作制度
- 施工单位工作制度流程
- 2026江西鹰潭市邮政分公司现面向社会招聘合同用工B类若干名备考题库及答案详解1套
- 2026四川成都市锦江区学府幼儿园招聘员额教师2人备考题库附答案详解(培优a卷)
- 2026广东华南理工大学前沿软物质学院文韬课题组科研助理岗位招聘1人备考题库及参考答案详解(a卷)
- 2026西藏拉萨发展集团有限公司招聘46人备考题库带答案详解(达标题)
- 2026江苏南通如东县岔河镇村卫生室工作人员招聘2人备考题库及参考答案详解(能力提升)
- 2026春季福建泉州市晋江市第五实验小学语文自聘教师招聘2人备考题库附参考答案详解(培优)
- JBT 6434-2024 输油齿轮泵(正式版)
- @SPC基础知识之二-SPC概念
- 2024年辽宁省交通高等专科学校高职单招(英语/数学/语文)笔试历年参考题库含答案解析
- 小小舞台剧变身戏剧表演家
- 幼儿园教师保密协议
- 独角兽企业:宁德时代组织结构及部门职责
- 教科版科学六年级下册全册同步练习含答案
- 接触网施工及方案设计
- 山西美锦华盛化工新材料有限公司化工新材料生产项目环评报告
- GB/T 20631.2-2006电气用压敏胶粘带第2部分:试验方法
- 知行合一读书分享课件
评论
0/150
提交评论