天天看點

tcl/tk學習筆記:字元串

教材:陳濤.Tcl 程式設計初步 tcl/tk入門經典(2)

1.幾個有用的指令

append              将值追加到字元串尾

format               字元串格式

scan                  字元串分解

binary                二進制字元串操作

string options    字元串操作和指令集

subst                 字元替代(替代特殊字元)

regexp               正規表達式(用于字元串模式比對)

regsub               用正規表達式進行字元串模式比對和替換

2.append 變量1 $變量2 将變量2的值追加到變量1的未尾。

3.format

與C 語言中的 printf 和 sprintf 函數的格式功能類似。

format spec value1 value2 ...

spec為格式說明字元串,valuex不變元,每個變元最多有6個關鍵詞:位置說明符、标志、字段寬度、精度、長度和轉換符。

格式轉換符與C類似,格式标志符:"-"表示左對齊,"+"右對齊,“space”在數字前沒有前導符時,加一個空格,"0"用0補空白,前導o為八進制,x為十六進制。

位置說明符i$表示從第i個變元取數值,從1開始。

例:set res [format "%2\$s" 1 5 9]   取第二個變元的值5。

      format "%o"20;        8進制輸出20,結果為24

      format "%x" 20;       16進制輸出20,結果為14

      format "%8x" 20;   16進制輸出20,寬8位,右對齊,結果為——————14,“—”表示空格

      format "%08x" 20; 16進制輸出20,寬8位,右對齊,左補0,結果為00000014

      format "%-8x" 20;  16進制輸出20,寬8位,左對齊

      format "%#x" 20;  16進制輸出20,字首為0x,結果是0x14

      format "%#8x" 20;16進制輸出20,字首為0x,結果是0x00000014

      format %c%e%c 40 30000 41;結果是(3.000000e+04),40和41的ASCII碼為"("和")",%e是科學記數法

4.scan string format var? var? ....

與format相反,scan根據格式描述符來解析一個字元串并将對應值賦給後面的變量,傳回成功轉換的個數,如果沒有指定輸出變量則傳回成功解析的結果。string是待解析的字元串,第二個是控制解析方式的格式字元串

後面的參數用來存儲轉換出的值。

例 scan "16 units,24.2% margin" "%d units,%f" a b;  結果是2 ;同時a = 16,b = 24.2

該操作同時掃描string和格式,除了被忽略的空格和制表符及% 字元,格式必須和字元串中的字元一一對應,上個例子中,16對應了%d,units,對應units,

24.2對應%f,格式不比對的字元解析将失敗。

有時候空格、制表符不能被忽略,如格式為%c時,%c是将string中的相應字元轉換為整型。

例 scan "a%2" "%c%c%c" a b c;運作結果為3,表示成功轉換了3個結果;a b c的值分别是97 37 51。

5.scan的幾個常見用途

一是簡單地解析字元串,上一小節中第一例這樣的例子

二是将ASCII字元轉換成對應的整型數字,上小節第二例如是

三是将可能是0開頭的數字組成的字元串轉換為整型數字

例 proc forceDecimal {x} {

             set count [scan $x {%lld %c} n c]

             if {$count != 1} {

                     error "not an interger"

             }

     return $n

     }

     set val 0987

     expr { [forceDecimal $val + 1]}

運作結果是988,如果沒有調用forceDecimal 函數,而是expr {$val + 1};則會報錯。%lld支援無限精度,可存儲任意大小的整數。

6.binary

對于數值來說,二進制(這裡說的二進制是資料在機器中的存儲方式,後面所說的八進制等隻是表現形式)可能比ASCII碼更省存儲空間,tcl提供了數字的ASCII碼和n進制碼的轉換:

binary format spec value1 ?value2 ...?  将數值類型轉換為ASCII

binary scan string spec var1 ?var2 ...?  與上相反

spec 為格式描述字元串

例 set b [binary format "s" 25664] ; 将整型數25664(在記憶體中占4位)轉換成字元串“25664”(在内中占5位),運作結果是"@d"。

                                                         25664的二進制表示是0110,0100,0100,0000,高8位是100,對應ASCII為"d",低8位是64,對應"@"

                                                         小寫的s是從低位開始排列,是以結果是"@d"。

    binary scan "@d" "s" var; 執行後puts $var的結果是25664  

    這裡的格式字元前沒有加"%",下面列出二進制轉換的格式字元

類型                              說明

 a              包含 count 個字元的字元串。在 binary format 中以空字元作為補白

 A              和 a 功能相同,隻不過使用空格符而不是空字元作為補白。

 b              長度為 count 的二進制字元串,以 0 和 1 組成,按照從低到高的 bit 位順序排列

 B              長度為 count 的二進制字元串,以 0 和 1 組成,按照從高到低的 bit 位順序排列

 h              長度為 count 的十六進制字元串,按照從低到高的位元組順序組成

 H              長度為 count 的十六進制字元串,按照從高到低的位元組順序組成

 c               一個 8 位字元編碼。binary scan 中會從字元串中将字元轉換為對應整數

 s               位元組順序為 little-endian 的 16 位整數。count 用于指定重複特性

 S              位元組順序為 big-endian 的 16 位整數。count 用于指定重複特性

 i               位元組順序為 little-endian 的 32 位整數。count 用于指定重複特性

 I               位元組順序為 big-endian 的 32 位整數。count 用于指定重複特性

 f               本機格式的單精度浮點數。count 用于指定重複特性

 d              本機格式的雙精度浮點數。count 用于指定重複特性

 x              使用 binary format 放置 count 個空位元組。使用 binary scan 跳過 count 個字

                 節

 X              回退 count 個位元組

 @             跳到由 count 指定的絕對位置。如果 count 為*則跳到末尾

有些字元在終端居然顯示不出來,比如224對應的ASCII字元,通常顯示成個這"" !?

7.subst

{}中的$,\,[,]等符是不做替換的,但需要替換的時候也可以用subst實作

set a hello!

subst [{a = $a}]  運作結果是a = hello!

如果改成:subst {[puts {a = $a}]b = $a}; 結果就是a = $a b = hello!;了解是,解析器解析的時候,先将{a = $a}傳遞給了puts指令,puts指令執行完全後,再

将結果a = $a 和 後面的字元串b = $a 傳遞給subst,因為解析器不對結果進行第二次解析,是以a = $a這裡不進行替換。