< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd>
先讓我們建立一個簡單的字元串,後面我們會常常操作它來示例:
var string = 'Laziness always pays off now.';
String.gsub
gsub 方法與JavaScript原生的 replace 方法類似,但它功能更強大。它接受兩個參數,第一個是需要搜尋的式樣(pattern)。它可以是一個簡單的字元串或者一個正規表達式。第二個參數則指定式樣比對的部分将被替換成的内容。
我們先從簡單開始,我不喜歡空格,是以讓我們把空格換成下劃線。
string.gsub(' ', '_');// Returns "Laziness_always_pays_off_now."
似乎沒什麼特别的,我們也可以直接用 string.replace(/\s/g, '_') 來完成類似的事情。不過當你意識到 gsub 的第二個參數可以是一個函數的時候就會發現 gsub 的發光點了。該函數對字元串中每個被比對的部分都将執行一次。它接受式樣比對後的 matches 數組(譯者著: JavaScript 的String.match() 方法傳回的數組)作為參數,接下來你就傳回一個被處理過後的字元串。聽起來有點迷糊?看代碼吧:
string.gsub(/\s\w/, function(match){ return match[0].toUpperCase(); });// Returns "Laziness Always Pays Off Now."
字元串中每個比對的部分都傳遞給參數函數,該函數處理被比對的部分并傳回替換後的版本。我們需要用 match[0] 來引用 match 對象是因為正規表達式的比對結果是作為一個數組傳回的。 數組中索引為0的值就是整個比對的内容,從第二個值開始則對應正規表達式中每個圓括号定義的組(group)的比對内容(譯者著:如果看不懂,請參閱正規表達式相關資料)。如果我們在正規表達式中使用了分組,那麼我們就能從 matches 數組中擷取這些元素。
string.gsub(/(s|f)(\s)/, function(match){ return match[1].toUpperCase() + '-' + match[2]; });// Returns "LazinesS- alwayS- payS- ofF- now."
String.sub
String.sub 同 String.gsub 幾乎一樣,但它能再多接受一個可選的參數。與gsub預設替換字元串中全部比對的内容不同,sub 隻替換由第三個參數指定個數的比對内容(預設是1個)。讓我們看原來的例子:
string.sub(' ', '_');// Returns "Laziness_always pays off now."
這一次,隻有第一個比對的空格被替換掉,如果我們傳入第三個參數再運作下面的例子,我們就可以看到不同了:
string.sub(' ', '_', 3);// Returns "Laziness_always_pays_off now."
其他方面,String.sub 和 String.gsub 一樣。(譯者著:可見 gsub 比 sub 多出來的 g 也就代表着正規表達式裡的 g 标記,該标記設定全文查找出現的所有 pattern)。
String.scan
scan 方法就是簡單的調用 gsub,傳入式樣和一個枚舉函數作為參數,該枚舉函數對比對的内容循環執行。
string.scan(/\w+/, alert);// Produces 5 alerts: "Laziness", "always", "pays", "off", "now"
另一個用法,就是可以用 scan 來擷取将所有比對結果的數組。
var results = [];
string.scan(/\w+/, function(match){ results.push(match[0].toUpperCase()); });// results = ['LAZINESS', 'ALWAYS', 'PAYS', 'OFF', 'NOW']
String.truncate
這個方法的用途正如你看名字後所期望的那樣,但有一些小機關(就我看來),truncate 由第一個參數指定的數目來截斷字元串,
string.truncate(15);// Returns "Laziness alw..."
似乎工作正常,不過它隻得到了12個字元而不是我們期望的15個。這是因為它還有一個可選的第二個字元類型參數,該參數将附在截斷的字元串之後,并且也參與傳回長度的計數。第二個參數預設是"...",做如下的修改就可以滿足我上面例子所希望得到的結果:
string.truncate(15, '');// Returns "Laziness always"
Template Class
最後,我們來談 Template 類,我認為它是一個漂亮的工作。它能讓我們構造一個字元串模闆,其中設定的變量可以在随後的代碼中進行替換。很象 PHP 的模闆或者任何我們見過的服務端模闆技術。預設的變量替換式樣是:#{variable_name}。 這裡有一個例子,展示如何建立一個模闆:
var linkTemplate = new Template('<a href="#{href}">#{text}</a>');
你可以随後調用它的 evaluate 方法,并傳入一個屬性名與變量互相對應的對象參數來渲染結果,如下:
linkTemplate.evaluate({href: 'http://www.google.com', text: 'The omnipotent one'});// Returns "<a href=" omnipotent one</a>"
數組它也支援:
var arrayTemplate = new Template('Original: #{0}, Sequel: #{1}');
arrayTemplate.evaluate(['Naked Gun', 'Naked Gun 2 1/2']);// Returns "Original: Naked Gun, Sequel: Naked Gun 2 1/2"
Customizing the Template Variable Pattern
足夠的靈活性,讓我們可以更深入的來定制自己的 Template 類。比如你已經擁有了一個優秀的模闆,但它是用PHP的short tag 文法編寫的。你做為一個懶惰的程式員,自然不願意再重寫模闆。不過不用擔心,付出一些努力對以後的逍遙是值得的。
Template 類構造器第二個可選參數正是一個定義變量替換式樣的正規表達式。預設值是常量Template.Pattern,其定義了很不錯的#{variable} 文法。而我們也可以定制自己的變量替換文法,試一下下面的代碼:
Template.PhpPattern = /(^|.|\r|\n)(<\?=\s*\$(.*?)\s*\?>)/;
現在,我們可以直接應用 PHP 模闆了,Prototype 魔術般的讓它工作了。
var phpTemplate = new Template('<div id="<?= $id ?>" class="<?= $class ?>"><?= $content ?></div>', Template.PhpPattern);
phpTemplate.evaluate({id: 'news', class: ['updated', 'arbitrary'].join(' '), content: '<p>No news is good news...</p>'});// Returns "<div id="news" class="updated arbitrary"><p>No news is good news...</p></div>"
如果你需要Ajax調用并傳回JSON資料,那麼這将對你很有幫助。你可以将頁面加載的PHP模闆建立為一個模闆對象,随後執行template的evalute方法并傳入Ajax請求得到的JSON對象作為參數。
當然,隻有在PHP模闆中不包含可能帶有隐患的業務/應用邏輯的時候,才建議這樣用。記住JavaScript可以通路的任何資訊也能被任何人看到。我建議你隻在簡單變量替換的需求中使用它。如果你大量使用,就要小心點了。
盡管我個人喜愛PHP模闆文法,我還是給出一個 Smarty 式樣來補充說明:
Template.SmartyPattern = /(^|.|\r|\n)({\$(.*?)\})/;
需要注意的一點就是,自定義的式樣必須符合 Template.Pattern 的正規表達式結構(譯者著:圓括号的數量與嵌套位置)。如果結構不是按照(beforePattern)(varSyntax(varName)) 的格式,模闆中的變量也許就不會被正确替換,因為它依賴于該格式産生對應的1, 2, 3 索引。
Coming Full Circle
現在,已經給大家展示了 Template 類,最後畫龍點睛給大家再秀一個String.gsub 和 String.sub 的小技巧,它們的第二個參數其實也可以是一個 Template 模闆字元串:
string.gsub(/\s/, '#{0}_');// Returns "Laziness _always _pays _off _now."
使用模闆字元串相比于使用一個函數做為作為第二個參數,變量比對的索引與傳遞給函數的matches數組索引是對應的。這有一個例子:
'Cory Hudson'.gsub(/(\w+) (\w+)/, '#{2}, #{1}');// Returns "Hudson, Cory"
注意此時模闆式樣不能象直接通過構造器建立Template對象那樣支援定義式樣文法。你隻能使用Ruby的文法,不過這用起來也不壞,不是嗎?
譯者著:
其實這樣的功能也可以用原生的replace方法來實作,比如:
'Cory Hudson'.replace(/(\w+) (\w+)/g, "$2, $1");
是以支援函數參數才是 gsub 強大之處。
Strings Can Be Fun!
使用Prototype給原生String對象提供的方法真是頗有趣味,它們能節省你不少編碼時間,而事實上,變幻的參數使得它們是如此靈活。
本文轉自 netcorner 部落格園部落格,原文連結:http://www.cnblogs.com/netcorner/archive/2007/08/17/2912300.html ,如需轉載請自行聯系原作者