<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    大漠駝鈴

    置身浩瀚的沙漠,方向最為重要,希望此blog能向大漠駝鈴一樣,給我方向和指引。
    Java,Php,Shell,Python,服務器運維,大數據,SEO, 網站開發、運維,云服務技術支持,IM服務供應商, FreeSwitch搭建,技術支持等. 技術討論QQ群:428622099
    隨筆 - 238, 文章 - 3, 評論 - 117, 引用 - 0
    數據加載中……

    Ruby學習1-字符串

    1,切片:silce, [ ]-----------------[ ]是silce的別名,所以兩者是完全相同的
    操作1:判定字符串中是否含有字串/子模式
    string[substring]
    string[/pattern/]
    string[/pattern/, position] #position之后的子串中是否含有/pattern/
    如果存在返回子串/子模式串,否則返回nil
    “hello world"["hello"]==="hello"
    "hello world"[/.*lo/]==="hello"
    "hello world"[/en/]===nil

    操作2:使用索引截取子串
    string[position] #注意返回的是ASCII碼而不是字符
    string[start, length]
    string[start..end]
    string[start...end]

    2,比較:
    == #比較字符串是否相等
    eql? #??好像沒有區別
    <=> #用來比較字符串的大小,大于返回 1,小于返回 -1, 否則返回0

    3,字符串的運算
    downcase #改變字符串為全部小寫
    upcase #改變字符串為全部大寫
    swapcase#反寫
    capitalize #改變字符串為首字母大寫
    * #重復字符串
    insert num, string #在num位置插入串string(insert沒有!,因為insert會直接改變原串)
    delete(!) string1 (,string2) #刪除string1交string2的字符
    gsub find, replace #將串中的find,替換為replace. find可以是正則表達式,replace很顯然不可以。注意:是所有相同的都替換,相當與sed中的s/pattern/string/g
    replace string #將字符串替換為string, 這是對象沒有變,只是其中的內容發生了變化。

    利用切片來改變字符串(silce!, [ ]=)
    "hello"["ello"]= "w" # "hw"
    "hello"[1]="wan" # "hwanllo"
    “hello"[1..3]= "wrd" #"hwrdo"
    "hello"[1...3]= "wr" #"hwrlo"
    "hello"[1,3]="wrd" #"hwrdo"
    "hello"[/el/]= "wr" #"hwrlo"

    chomp(!) 用來摘除字符串末尾的換行符(如果不是換行符返回空)#注意只能是換行符,空格都不行
    chop(!)用來摘除字符串末尾的最后一個字符
    reverse(!)首尾倒置
    split(/pattern/)將字符串分割成數組,分隔符是/pattern/(注意帶!的方法不能用來改變類,所以split沒有?。?br />

    字符串長度
    string.length
    string.size

    字符串對齊
    string.ljust num, char #用char來填充string,不足num的部分。注意左對齊是右填充。如果字符串長度比char大,忽略
    string.rjust num, char
    string.center num, char

    string.lstring #trim字符串,去除左邊空格
    string.rstring
    string.strip
    ..........那么如何去掉所有的空格呢? 很簡單,使用gsub,進行替換

    string.next/succ #string+1 不是+1這么簡單。"a".next == "zz"
    string1.upto(stringn) #string1, string2 ....stringn

    字符串遍歷:
    string.each #分割不同項的必須是\n "hello\nworld".each {|e| puts e << ","}===
    hello,
    world,
    "hello world".each{|e| puts e << ","}===
    hello world,
    string.each_byte #以字節為單位遍歷



    求字串的索引位置
    string.index substring #正則表達式也可以

    正則表達式專用
    string.grep /pattern/ #如果不是正則表達式搜索不到任何東西,如果是且匹配返回包含整個字符串的一個數組
    string =~ /pattern/ #pattern第一次出現的位置
    string !~ /pattern/ #如果沒有找到/pattern返回true(注意!)


    uby很強大,可是相關資料少而不詳細。本文是個人學習總結,測試環境是windows xp sp3 + NetBeans6.7.1(JRuby 1.2.0),主要結論來自于互聯網、"Programming Ruby"2e、對于源代碼的分析和實測代碼。

    雙引號字符串和單引號字符串

    都能表示字符串對象,區別在于雙引號字符串能夠支持更多的轉義字符。下面的代碼在字符串中增加了'符號。
    str=‘he'lo’
    puts str
    顯示結果為he'lo。

    單引號僅支持\\ => \ 和 \' => '

    下表是ruby中雙引號字符串支持的轉義字符:

    分界符


        所有不是字母或者數字的單字節字符都可以成為String的分界符。注意,通常他們都是成對出現的,比如<和>,!和!,{和}等。

    構造字符串字面量

    方法一:
    最簡單的使用單引號或者雙引號括起來的字符串,比如"hello"。

    方法二:
    使用%q配合分界符,%q代表單引號
    str=%q!he\lo!

    方法三:
    使用%Q配合分界符,%Q代表雙引號
    str=%Q{he\lo}

    方法四:
    here document構建字符串,該方法比較適合用于多行字符串的創建。由<<和邊界字符串作為開頭,由邊界字符串作為結尾,比如下列代碼:
    str = <<END_OF_STRING1
      We are here now,
      where are you?
    END_OF_STRING1
    puts str
    輸出結果為:
      We are here now,
      where are you?

    較為復雜的是允許多個邊界字符串對出現。
    str = <<END_OF_STRING1,<<END_OF_STRING2
      We are here now,
      where are you?
    END_OF_STRING1
      I will leave now,
      would you like to go with me?
    END_OF_STRING2

    puts str
    輸出結果為:
      We are here now,
      where are you?
      I will leave now,
      would you like to go with me?

    字面量與copy-on-write技術


        在Java中,如果兩個String對象a和b的值都是"abcdef",如下:
    String a="abcdef";
    String b="abcdef";
    那 么,JVM只會創建一個常量對象"abcdef",讓a和b都指向它。但是在ruby中,采用了智能指針(熟悉c++的朋友清楚)的一個高級技術 copy-on-write,一開始也是共享同一個字符常量,但是一旦之后某個對象(比如b對象)進行了修改操作,則"abcdef"將產生一個副本,b 的修改操作在這個副本上進行。
        更詳細的討論請參考http://developer.51cto.com/art/200811/98630.htm。

    和Java的一些其他區別

        Java的String每次執行修改操作,都不會改變自身,而是創建一個新的String對象,而Ruby每次的修改操作都會修改自身。

    計算長度

    puts "hello".length
        該句輸出5,是字符個數,不要和C函數搞混,C函數經常用0結束字符串,因此長度經常為實際字符個數+1,Ruby中沒有這個習慣。

    查找

    從左向右查找第一個

        index方法有三種重載,分別是:
    str.index(substring [, offset]) => fixnum or nil
    str.index(fixnum [, offset]) => fixnum or nil
    str.index(regexp [, offset]) => fixnum or nil

        第二個參數offset是可選參數,不用的話則從索引0的字符開始查找。
    puts "hello".index("el") 輸出為1 ,注意這里的'el'也可以。也可以只查一個字符比,如puts "hello".index(101) 輸出為1,這時候第一個參數為'e'的二進制碼。
    也可以使用正則表達式進行查找,比如puts "hello".index(/[az]/) 輸出為nil,因為"hello"不包含a或者z。[]是正則表達式的運算符,代表里面的a和z有一個找到即可。
    puts "hello".index(/lo/) 這個沒有[]符號,因此是查找子字符串lo,結果為3.
        我個人覺得盡量熟練使用正則表達式查找是最好的選擇,既可以完成簡單查找,也可以完成難度查找。不過需要付出不少努力去學習。
        下面這個例子puts "hello".index('o', -1) 證明了第二個參數可以為負數,雖然這沒有什么意義,因為功能和為0等價。
        如果查找不到,返回nil。

    逆向查找(從左向右查找最后一個還是從右向左查找第一個)

    str.rindex(substring [, fixnum]) => fixnum or nil
    str.rindex(fixnum [, fixnum]) => fixnum or nil
    str.rindex(regexp [, fixnum]) => fixnum or nil
       
        第一個參數和index相同,第二個參數是可選,如果不用則默認為字符串尾部。如果為0呢?則從第一個字符開始向右查找。如果為負數呢?這時候很奇怪,居 然能查到。通過看C的實現代碼,發現當fixnum<0時,會執行這個運算:fixnum+=substring.length,然后就能找到。邏 輯上可以理解為當fixnum<0時,將從最右邊開始向左移動abs(fixnum)-1個位置,并作為最后查找范圍,然后開始從左至右進行查找。 字符串最右邊的字符的位置被-1代表。
    下面兩行代碼結果都是nil:
    puts "hlloe".rindex('e', -2)
    puts "hlloe".rindex('e', 3)

    下面兩行代碼結果都是1:
    puts "hello".rindex('e', -2)
    puts "hello".rindex('e', 3)

        注意,以上的代碼理解是我個人觀察代碼后的猜測,因為我還不會調試運行ruby的C代碼,所以不一定正確。代碼摘錄如下:(代碼是ruby網站公布的C代 碼,但是我所用的平臺其實NetBeans6.7.1,因此真正代碼應該是Java實現的JRuby1.2.0,這里的C代碼僅供參考)
    static VALUE
    rb_str_rindex_m(argc, argv, str)
        int argc;
        VALUE *argv;
        VALUE str;
    {
        VALUE sub;
        VALUE position;
        long pos;

        if (rb_scan_args(argc, argv, "11", ⊂, &position) == 2) {
            pos = NUM2LONG(position);
            if (pos < 0) {
                pos += RSTRING(str)->len;
                if (pos < 0) {
                    if (TYPE(sub) == T_REGEXP) {
                        rb_backref_set(Qnil);
                    }
                    return Qnil;
                }
            }
            if (pos > RSTRING(str)->len) pos = RSTRING(str)->len;
        }
        else {
            pos = RSTRING(str)->len;
        }

        switch (TYPE(sub)) {
          case T_REGEXP:
            if (RREGEXP(sub)->len) {
                pos = rb_reg_adjust_startpos(sub, str, pos, 1);
                pos = rb_reg_search(sub, str, pos, 1);
            }
            if (pos >= 0) return LONG2NUM(pos);
            break;

          case T_STRING:
            pos = rb_str_rindex(str, sub, pos);
            if (pos >= 0) return LONG2NUM(pos);
            break;

          case T_FIXNUM:
          {
              int c = FIX2INT(sub);
              unsigned char *p = (unsigned char*)RSTRING(str)->ptr + pos;
              unsigned char *pbeg = (unsigned char*)RSTRING(str)->ptr;

              if (pos == RSTRING(str)->len) {
                  if (pos == 0) return Qnil;
                  --p;
              }
              while (pbeg <= p) {
                  if (*p == c) return LONG2NUM((char*)p - RSTRING(str)->ptr);
                  p--;
              }
              return Qnil;
          }



    通常我們理解為從右邊開始查找,但是注釋卻表明是從左向右查找,并返回最后一個找到的目標的位置。究竟內幕如何,只能看代碼。
    01161 static long
    01162 rb_str_rindex (str, sub, pos)
    01163 VALUE str, sub;
    01164 long pos;
    01165 {
    01166 long len = RSTRING (sub)->len;
    01167 char *s, *sbeg, *t;
    01168
    01169 /* substring longer than string */
    01170 if (RSTRING (str)->len < len) return -1;
    01171 if (RSTRING (str)->len - pos < len) {
    01172 pos = RSTRING (str)->len - len;
    01173 }
    01174 sbeg = RSTRING (str)->ptr;
    01175 s = RSTRING (str)->ptr + pos;
    01176 t = RSTRING (sub)->ptr;
    01177 if (len) {
    01178 while (sbeg <= s) {
    01179 if ( rb_memcmp (s, t, len) == 0) {
    01180 return s - RSTRING (str)->ptr;
    01181 }
    01182 s--;
    01183 }
    01184 return -1;
    01185 }
    01186 else {
    01187 return pos;
    01188 }
    01189 }

        通過看代碼,發現s--;因此,是從右向左進行匹配,找到的第一個就返回。寫注釋的人應該槍斃!雖然看上去意思一樣,但是算法的時間復雜度大不一樣。從左到右的查找總是O(n),而從右到左的最壞事件復雜度才是O(n)。

    大小寫不區分查找

        puts "hello".upcase.index("H"),利用downcase或者upcase全部轉換成小寫或者大寫,然后再查找。

    正則表達式匹配查找

    operator =~ 將返回匹配的模式開始位置,如果沒有找到則返回nil。
    puts "abcde789" =~ /d/
    輸出5.

    提取子字符串

    str="hello"
    puts str[0,2]
    第一個參數是子字符串首字母的Index,第二個是長度(不能為負數)。
    結果為he。
    第一個參數可以為負數,會把最右邊的字符作為-1,然后向左增加-1的方式查找起始位置,比如:
    str="hello"
    puts str[-2,2]
    輸出為lo,這種情況我們在rindex方法中已經看到過了。

    也可以使用正則表達式進行提取,這真的很強大。
    str="hello"
    puts str[/h..l/]
    輸出為hell。

    符號.代表一個字符,兩個.代表兩個字符。兩個/里面的內容就是正則表達式。.*代表可以有無數個字符,比如
    str="hello"
    puts str[/h.*o/]
    輸出為hello。

    字符計數

    String#count用來計算我們參數中給出的字符集中字符出現的總次數,比如最簡單的情況:
    str = "hello,world"
    puts str.count "w"
     “w" 參數代表的是一個字符結合,里面只有一個字符w,count方法計算出w出現在"hello,world"的次數是1,因此輸出為1。
    下面我們的參數里面包含了三個字符:
    str = "hello,world"
    puts str.count "wld"
    輸出為5,w出現1次,l出現3次,d出現1次,正好5次。

    也可以傳遞多個參數,每個參數代表一個字符集合,這時候這些字符集合的交集作為count計算的條件:
    str = "hello,world"
    puts str.count "lo","o"
    輸出為2。
    str = "hello,world"
    puts str.count "lo","o"," "
    輸出為0,因為三個集合的交集為空,所以計算結果為0.

    注意,如果參數^o,代表o出現的次數不計算。

    刪除末尾分隔符

    String#chomp方法有一個字符串參數,指定了要在末尾刪除的子字符串。如果不用這個參數,則會將字符串末尾的n,r和rn刪除(如果有的話)。

    壓縮重復字符

    String#squeeze方法如果不用參數,則會將字符串中的任何連續重復字符變成單一字符,如下:
    str = "helllloo"
    puts str.squeeze
    輸出:helo。
    如果傳遞字符串參數,含義同count方法的參數一樣,代表了一個字符集合,則將符合條件(1,在字符集合中出現;2,在字符串中連續出現)的子字符串壓縮成的單一字符
    實例代碼如下:
    str = "helllloo"
    puts str.squeeze('l')
    puts str.squeeze('a-l')
    puts str.squeeze('lo')
    輸出為:
    heloo
    heloo
    helo

        參數也可以用a-z方式表示在某個字符集合區間內。

    一個很常用的功能是利用squeeze(" ")對字符串內重復的空白字符進行壓縮。

    字符串刪除

    delete方法

    可以接收多個參數,每個參數代表一個字符集合,類似count方法。如果有多個參數,取交集,然后從字符串中刪除所有出現在交集中的字符。
    "hello".delete "l","lo" #=> "heo"
    "hello".delete "lo" #=> "he"
    "hello".delete "aeiou", "^e" #=> "hell"
    "hello".delete "ej-m" #=> "ho"

    利用sub和gsub

    參見后面的sub用法,使用''進行替換即可。

    字符串拆分

    String#split接收兩個參數,第一個參數總是被作為間隔符來拆分字符串,并且不會出現在結果中。
    第一個參數如果是正則表達式的話,如果為空,則每個字符都被拆開,返回一個字符數組。例子代碼如下:
    str = "hello"
    puts str.split(//)
    輸出為:
    h
    e
    l
    l
    o

        如果正則表達式不為空,則根據匹配的情況進行拆分。例子代碼如下:
    str = "hello"
    puts str.split(/h/)
    結果為:

    ello

    拆分成了兩個數組,第一個為"",第二個為ello,用h進行拆分的。
    第一個參數的另一種用法很簡單,只是一個字符串,用于作為間隔符進行拆分,就不舉例子了。我更傾向于使用強大的正則表達式。

    第二個參數是一個整數,用于對拆分的結果數組的元素個數進行限制,這個功能有多大用處,我現在到沒有體會,一般情況下不用即可。

    大小寫轉換

        如前面出現的,利用downcase或者upcase方法即可。

    數組操作

    使用[],里面填上Index,就可以獲取第Index個元素。

    和數值類型的相互轉換


    獲取單字節字符的二進制碼
    puts ?e
    ?運算符用于中文是非法的。

    字符串迭代

    Ruby迭代器的設計不在這里討論,我會專門有一篇文章描述。

    each_char

    迭代每個字符,下面是示例代碼:
    require 'jcode' #NetBeans6.7.1和JRuby1.2.0需要,否則下面代碼找不到方法
    "hello".each_char(){ |c| print c,' ' } #()可以不寫

    |c| 代表字符串中的當前字符。

    each

    迭代每個子字符串,如果不傳遞seperator參數,則默認用n作為seperator。
    "hellonworld".each { |c| puts c }
    輸出為:
    hello
    world

    如果傳遞了有效的字符串作為seperator參數,那么就以這個seperator代替n進行子字符串的迭代:
    "hellonworld".each('l') { |s| p s }
    輸出為:
    "hel"
    "l"
    "onworl"
    "d"

    each_byte

    用法和each_char類似,不過迭代的對象是char,因此輸出的是二進制數值。
    "hellonworld".each_byte { |s| print s," " }
    輸出:
    104 101 108 108 111 10 119 111 114 108 100

    each_line

    用法和前面相同,只是用換行符分割子字符串進行迭代:
    "hellonworld".each_line do |s|
      print s
    end
        注意,這是另一種寫法,用do/end替換了{/}對。
    輸出為:
    hello
    world
    只所以輸出為兩行,是因為第一個子字符串是"hellon"輸出后自動換行。

    字符串拼接

    使用operator +操作

    str1="hello,"
    str2="world"
    str3=str1+str2
    puts str3
    輸出為hello,world

    使用operator <<操作

    str1="hello,"
    str2="world"
    str1<
    puts str1
    輸出為hello,world

    concat方法

    concat方法可以在字符串后面加上一個二進制值為[0,255]的字符,用法如下:
    str1="hello,world"
    str1.concat(33)#33是!的二進制值
    puts str1
    輸出為hello,world!

    concat也可以接一個object,比如另一個String對象

    是否為空

    String#empty? 方法 如果為空返回true,否則返回false

    字符串比較

    operator<=>操作

    str1<=>str2
    如果str1小于str2,返回-1;
    如果str1等于str2,返回0;
    如果str1大于str2,返回1。

    官方注釋寫反了。

    operator==操作

    兩個比較對象必須都為String,否則返回false;
    如果都是String對象,則調用operator <=> 操作符進行比較,比較結果為0時,返回true,否則返回false

    字符串替換

    replace方法

    和operator = 功能相同,字符串內容的完全替換,沒什么作用。

    sub方法

    str.sub(pattern, replacement) => new_str
    str.sub(pattern) {|match| block } => new_str


    在str副本上將找到的第一個匹配字符(串)用replacement替換,并返回。比如:
    puts "abcde789".sub(/d/, "000")
    輸出為:abcde00089

    第二種重載形式允許執行一段代碼,比如:
    puts "abcde789".sub(/d/){|c| 'a'}
    找到的字符用|c|表示,可以替換成a字符
    輸出為:abcdea89

    gsub方法

    和sub的區別在于所有匹配的地方都會被替換,而不只是第一個。

    posted on 2010-01-03 16:22 草原上的駱駝 閱讀(4061) 評論(0)  編輯  收藏 所屬分類: Ruby

    主站蜘蛛池模板: 国产一级一毛免费黄片| 免费高清在线影片一区| 久久黄色免费网站| 浮力影院第一页小视频国产在线观看免费 | 亚洲av无码一区二区三区不卡 | 一个人免费观看视频www| 亚洲国产成人久久笫一页 | 亚洲欧美日韩中文高清www777| 你是我的城池营垒免费看| 国产色婷婷精品免费视频| 亚洲另类精品xxxx人妖| a级毛片毛片免费观看永久| 亚洲人成色77777| 黄页视频在线观看免费| 成年在线观看网站免费| 亚洲人成无码网站在线观看| 日本不卡在线观看免费v| 亚洲乱码日产精品BD在线观看| 一二三四影视在线看片免费| 亚洲日韩精品无码专区加勒比| 日本人的色道www免费一区| 一区二区免费在线观看| 国产精品99久久免费| 日韩成人毛片高清视频免费看| 国产精品四虎在线观看免费| 色网站在线免费观看| 亚洲阿v天堂在线| 久久免费香蕉视频| 久久精品亚洲乱码伦伦中文| 杨幂最新免费特级毛片| 亚洲国产精品va在线播放| 亚洲网站免费观看| 亚洲福利电影一区二区?| 日本在线看片免费| 亚洲一区二区无码偷拍| 成人女人A级毛片免费软件| 美女的胸又黄又www网站免费| 久久精品国产69国产精品亚洲| 69成人免费视频无码专区| 亚洲国产乱码最新视频| 精品无码国产污污污免费|