張智星 (Roger Jang) jang@mirlab.org http://mirlab.org/jang 清大資工系 多媒體檢索實驗室 第十章:字元與字串 張智星 (Roger Jang) jang@mirlab.org http://mirlab.org/jang 清大資工系 多媒體檢索實驗室
本章簡介 本章介紹 MATLAB 用於處理字元(Characters)與字串(Strings)的指令及相關資料型態。MATLAB 處理字串的相關指令大部分都放在下列目錄之中: {MATLAB 根目錄}\toolbox\matlab\strfun 其中的「strfun」就是代表「String Functions」。若要查詢與字元和字串相關的指令,可在 MATLAB 下輸入: help strfun help strings
10-1 字元與字串的基本概念 數個字元(Characters)可以構成一個字串(Strings) 一個字串是被視為一個列向量(Row Vector)進行儲存 此一字串中的每一字元(含空白字元),是以其 ASCII 碼的形式存放於此列向量中的每一個元素
字元與字串的基本概念 Matlab 用「單引號」來界定字串變數,多個字串變數可直接並排,以得到一個新字串變數,例如: 範例10-2: string102.m str3 = I like MATLAB, JavaScript, and C++! str1 = 'I like MATLAB,'; % 建立字串變數 str1 str2 = ' JavaScript, and C++!'; % 建立字串變數 str2 str3 = [str1 str2] % 直接並排str1 及 str2,以建立str3
字元與字串的基本概念 欲輸入含有單引號的字串,可重覆單引號的使用 若要計算字串變數的長度(即組成字元的個數),可用 length 指令 範例10-4: string104.m ans = 16 sentence = 'I''ve got a date!'; length(sentence) % 計算字串變數 sentence 的長度
字串和其ASCII code double 指令: 檢視字串變數的儲存內容(即 ASCII 內碼) char 指令: 將 ASCII 內碼轉回字串形式 範例10-6: string106.m sentence2 = I've got a date! sentence = 'I''ve got a date!'; sentenceAscii = double(sentence); %檢視 sentence 的 ASCII 碼 sentence2 = char(sentenceAscii) % 將 ASCII 碼轉回字串形式
字元的儲存 無論是中文或英文,每一個字元都會佔用兩個位元組(2 Bytes),故在上頁中,字串變數 sentence 總共由 16 個字元構成,佔用的記憶體總計為三十二個位元組(32 bytes) whos 指令: 檢視字串變數 sentence 所佔用儲存空間 MATLAB 是以兩個位元組來儲存一個字元,所以也可以支援中文(MATLAB內部都是以unicode來儲存),而且 中文的 ASCII 內碼都會大於數字 128 由於 MATLAB 將字串以其相對應之 ASCII 內碼(即數字形式)儲存成一列向量,故若對此字串直接進行數值運算,MATLAB 會先將此字串轉成數值,再進行一般數值向量的運算
字元與字串的基本概念-eval eval 指令: 直接“執行”某一特定字串,其效果就如同直接在 MATLAB 指令視窗內輸入此一特定字串 eval 指令特別適用於在 for-loop 內自動產生有規律的變數名稱 範例10-11: string111.m Name Size Bytes Class x3 3x3 72 double array x4 4x4 128 double array x5 5x5 200 double array x6 6x6 288 double array Grand total is 86 elements using 688 bytes x3 , x4 , x5 , x6 都是在 for-loop 中產生的變數,分別代表維度為 3×3、4×4、5×5、6×6 的魔方陣 clear all % 清除所有變數 for i = 3:6 eval(['x', int2str(i) , '= magic(' , int2str(i) , ') ; ']); end whos x*
字串的判斷 class 或 ischar 指令: 判斷某一個變數是否為字串 範例10-12: string112.m 字串變數所佔用的空間是同長度雙精準(Double)數值變數的四分之一 chinese = '今日事,今日畢'; out1 = class(chinese) % out1 的值是 “char”,代表chinese 是字串變數 x = chinese+1; out2 = ischar(x) % out2 的值是 0,代表 x 不是一個字串變數
10-2 一個變數來儲存多個字串 第一種方法是使用二維字元陣列(Two Dimensional Character Arrays) 必須先確認每個字串(即每一橫列)的長度一樣,否則就必須在短字串結尾補上空白字元 範例10-13: string201.m departments = ee cs econ departments = ['ee '; 'cs '; 'econ'] % 注意空白字元的使用
一個變數來儲存多個字串 用char 指令儲存多個字串 得到結果和前一個範例依樣; 從二維字元陣列抽取出字串時,切記要使用 deblank 指令來移除尾部的空白字元 範例10-15: string203.m . departments = char('ee', 'cs', 'econ') % 注意「()」及「,」的使用 departments = char('ee', 'cs', 'econ'); dept1 = departments(1,:); % (1,:)代表第一列的元素 dept2 = deblank(dept1); % 使用 deblank 指令來移除尾部的空白字元 len1 = length(dept1) % 顯示變數 dept1 的長度=4 len2 = length(dept2) % 顯示變數 dept2 的長度=2
一個變數來儲存多個字串 當字串的長度差異甚大,那麼使用二維字元陣列來儲存多個字串,將造成記憶體空間的浪費,怎麼辦? 「異質陣列」: 使用大括號框住多個字串, 或用cellstr指令將字元陣列轉換成異質陣列 (string204.m,string205.m) 若要將包含字串的異質陣列轉換成一般的二維字元陣列,還是可以使用 char 指令
10-3 字串的比較、尋找、 代換、分解與結合 strcmp 指令: 用於比較字串內容的異同 範例10-19: string301.m 不相等回傳 0,相等回傳 1,和 C 程式語言的strcmp()函數剛好相反,要特別注意! str1 = 'today'; str2 = 'tomorrow'; str3 = 'today'; out1 = strcmp(str1, str2) % 比較兩字串 str1 和 str2 = 0 out2 = strcmp(str1, str3) % 比較兩字串 str1 和 str3 = 1
字串的比較和尋找 strncmp:用於比較字串的前 n 個字元 strcmp 及 strncmp 指令亦可用於字串異質陣列 findstr:尋找在某一個長字串中的子字串(Substrings),並傳回其起始位置 strrep:用於字串尋找及代換,例如: newString = strrep(string, pattern, pattern2)
字串的分解 strtok 指令: 根據一給定的分界字元(Delimiting Characters),將一字串拆解成數個字串,預設分界字元為空白字元 strvcat 指令: 將拆解下來的字串內容(即儲存在字串變數 chopped 中) 加到二維字元陣列 parsed 中 範例10-24: string306.m parsed = ee cs econ stat me input_string = 'ee cs econ stat me'; remainder = input_string; parsed = ''; % 建立一空字元陣列 while (any(remainder)) [chopped, remainder] = strtok(remainder); parsed = strvcat(parsed, chopped); end parsed
字串的結合 MATLAB 在讀入中文字串時,將每一個中文字的 2-byte 分開來讀,造成兩個中文字變成四個字串元素 native2unicode可將中文的 2-byte 「結合」在一起 範例10-27: string309.m line2 = 我是Roger ans = 7 (註:這個中文讀取問題在MATLAB7.2版之後,已經解決了!) fid = fopen('big5.txt'); line = fgetl(fid); % 讀取一列檔案內容 fclose(fid); line2 = native2unicode(line, 'big5') %將被拆開的中文字結合在一起 leng = length(line2) % 顯示字串長度
10-4 字串、數值與陣列的轉換 int2str 指令: 將整數型態的資料轉換成字串資料 例如:y = int2str(x),x為整數, y 為字串 num2str 指令: 將實數轉為字串 dec2hex 指令: 將 10 進位數值資料轉換成 16 進位的字串表示法 更多類似指令如 : hex2num, hex2dec, bin2dec….
字串陣列的轉換 mat2str 指令可將矩陣轉換為字串,此字串若再經由 eval 指令,可再變回原先的矩陣 範例10-32: string405.m B = [1 2 1;3 5 6] ans = 1 A = [1 2 1; 3 5 6 ]; B = mat2str(A) % 將矩陣 A 轉成字串 B A2 = eval(B) % 再將字串 B 轉回矩陣 A2 isequal(A, A2) % 測試 A 和 A2 是否相等
字串與數值的結合 sprintf 指令: 結合數值或字串,以產生新字串 (%s-印出字串, %g-印出數值,可使用 %f 或加上控制印出位數大小的數字 ) 範例10-33: string406.m newString = 「圓周率」是 3.14159 sscanf 可依給定的格式來解析出所要的字串或數值 範例10-34: string407.m mat = 2.0000 4.7000 5.2000 str = '圓周率'; newString = sprintf('「%s」是 %g', str, pi) str = '2 4.7 5.2'; mat = sscanf(str, '%f')