搜索關鍵字符串NSSCanner:scanUpToString和scanString

轉載:http://blog.csdn.net/kmyhy/article/details/8258858


假設我們查找某個關鍵字(比如:【來自網易郵箱的超大附件】)在某段文本中的位置。這段文本的內容是不固定,它可能是這樣的:

 

【來自網易郵箱的超大附件】

提示:郵件帶有附件預覽鏈接,若您轉發或回覆此郵件時不希望對方預覽附件,建議您手動刪除鏈接。

 

也可能是這樣的:

 

開其說頗參差,而皆近於附會,故黃宗羲至詆爲經緯混淆,行度無稽。【來自網易郵箱的超大附件】

提示:郵件帶有附件預覽鏈接,若您轉發或回覆此郵件時不希望對方預覽附件,建議您手動刪除鏈接。

 

還有可能根本不包含關鍵字:

 

achartengine

 繪製統計圖是 就一個系類  能讓這個系類中每個柱形圖的顏色都不一樣嗎

 

我們需要把關鍵字“【來自網易郵箱的超大附件】”之後的內容統統刪除,只保留位於關鍵字之前的內容,比如第一段文字變成了空或者第二段文本只留下以下文字:

 

開其說頗參差,而皆近於附會,故黃宗羲至詆爲經緯混淆,行度無稽。

 

這個任務可以用NSScanner來做,如以下代碼片段:

 


-(NSString*)extractBodyFromMessage:(NSString* )msg{

    NSString* body=msg;

    NSString* keyString=@"【來自網易郵箱的超大附件】";

    NSScanner*scanner=[NSScanner scannerWithString:body];

    [scannersetCaseSensitive:NO];

    BOOL b;

    while (![scanner isAtEnd]){

        b=[scannerscanString:keyString intoString:NULL];

        if(b) {

           body=[body substringToIndex:[scanner scanLocation]-keyString.length];

           break;

       }else{

           scanner.scanLocation++;

        }

    }

    return body;

}

 

在while循環裏面,我們首先從0位置開始掃描指定關鍵字,如果未找到,移動scanLocation位置,繼續從下一字符查找直至文本末尾;如果找到,直接返回子字符串。

有人會覺得用scanUpToString代替scanString會更好。

因爲,scanUpToString在找到指定文本(keyString)後,會將scanLocation停止在keyString之前(scanString方法會將scanLocation移到keyString之後位置),這樣我們的substringToIndex:方法就不必再用scanLocation減去keyString的長度了:

 

body=[bodysubstringToIndex:[scanner scanLocation]];

 

你可以試試,用scanUpToString替換scanString,並將substringToIndex:一句改成上面的語句,會是什麼結果。

對於第一段文本來說,結果會是:

 

【來自網易郵箱的超大附件】

提示:郵件帶有附件預覽鏈接,若您轉發或回覆此郵件時不希望對方預覽附件,建議您手動刪除鏈接。

 

似乎scanner並沒有找出keyString關鍵字。爲什麼?

因爲API文檔裏面說:

 

If stopStringis the first string in the receiver, then the method returns NO and stringValue is not changed.

 

如果scanUpToString在文本的開頭(第一個字符)就找到目標文本,會返回NO,stringValue不會改變。

 

對於第一段文字來說,keyString就在文本的開頭。因此scanUpToString雖然找到了keyString,但它仍然返回NO,並且scanLocation是0。於是從第2個字符又繼續查找。結果當然是找不到,一直到最後一個字符之前,然後scanLocation++,scanLocation變成了最後一個字符的索引。

 

對於第二段和第三段文本,scanUpToString得到的結果倒是和scanString是一致的。沒有什麼問題。

這是因爲API文檔中說了:

 

If stopStringis present in the receiver, then on return the scan location is set to thebeginning of that string.

If the search string (stopString) isn't present in the scanner's source string, theremainder of the source string is put into stringValue, the receiver’s scanLocation is advanced to the end of thesource string, and the method returns YES.

 

如果目標文本在receiver文本中被找到,返回YES並將scanLocation設置到已找到的目標文本之前。

如果目標文本未找到,從本次查找開始剩下的整個receiver文本被放入stringValue,scanLocation移動到源串的末尾,返回YES。

 

很顯然,對於scanUpToString和scanString的區別,最主要的就在第一種情況上。如果目標文本一開頭就出現目標文本(scanner默認是忽略空格和換行的,因此如果開頭有這兩個空白字符,scanner視若未見),二者將得到完全不同的結果:scanString會返回YES,而scanUpToString返回NO。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章