2014-03-28 64 views
0

我需要搜索某些內容並用HTML包含某些單詞。要搜索的單詞在數組中,我只想替換每組匹配中的第二個到最後一個匹配項。因此,舉個例子,如果有5場比賽,我想替換第4場比賽。如果有3場比賽,請更換第2場。如果有2個匹配,則替換第二個/最後一個匹配,如果只有一個匹配,則使用該匹配。需要計數匹配並使用preg_replace_callback替換「第n個」匹配

回調函數在使用回調函數的外部。

我想我需要一個數組 - 減一 - 然後將該數字傳遞給回調函數並在那裏使用它,但也許有更簡單的方法來做到這一點?

簡化的功能是:

function repWords($content) { 
    foreach ($words_array as $w) { 
     $content = preg_replace_callback('/\b('.$w.'[s]?)\b/S', array(&$this,'addHtml'), $content); 
    } 

    return $content; 
} 

function addHtml($format){ 
    return '<span>' . $format[1] . '</span>' 
} 

根據需要更換它找到的話,我可以將它設置爲隨機替換一些這樣的作品,但我想要麼更換第n個發生和/或僅替換一個發生(並不總是第一次出現)。

+0

最後一段引發我的興趣,似乎沒有與你以前的陳述jive。你可以給一個實際的「之前」和「之後」的例子? –

+0

所以你不希望這個方法是正確的:在數組中找到所有匹配的單詞,將'count-1'傳遞給回調函數? – mesutozer

+0

也,你使用什麼版本的PHP –

回答

1

根據您的要求,這裏是我想出了:

// needs to be global given that you are using non-anonymous function syntax 
$count = 0; 

function repWords($content) { 
    global $count; 

    $words_array = array('some','content','foobar'); 

    foreach ($words_array as $w) { 
    $pattern = '~\b('.$w.'s?)\b~'; 
    $count=0; 
    preg_match_all($pattern,$content,$matches); 
    $count=count($matches[0]); 
    if ($count>0) 
     $content = preg_replace_callback($pattern,'addHtml',$content); 
    } 
    return $content; 
} 

function addHtml ($format) { 
    global $count; 
    static $cc=1; 
    static $pf=''; 

    $val=$format[1]; 
    $cc = ($pf!=$val) ? 1 : ++$cc; 

    if ((1==$count)||($cc==($count-1))) 
    $format[1]= '<span>' . $val . '</span>'; 

    $pf=$val; 
    return $format[1]; 
} 


$content = <<<EOC 
this is some content 
some more content 
this content foobar 
EOC; 

echo repWords($content); 

輸出

this is <span>some</span> content 
some more <span>content</span> 
this content <span>foobar</span> 
  • 第一 「一些」 是包裹,因爲有2個實例其中
  • 第二個「內容」被封裝,因爲有3個實例它
  • 「foobar的」包裹,因爲只有1它

注意的實例:這種利用全局變量$count。一般來說,使用全局變量是一個糟糕的主意。但是,如果您選擇單獨定義回調而不是使用匿名函數,則由於php和preg_replace_callback(或任何可以指定回調的函數)的限制,這是少數幾個勉強接受的示例之一。如果您使用的是php5.3 +並且願意將addHtml改爲匿名函數,則可以使用use$count傳遞給匿名函數。或者,如果所有這些實際上都在一個類中,請將其設爲類屬性,並使用$this->count來代替。

另注:你說的是「(並不總是第一個出現)」我是有點這種困惑,把它可能意味着你想以某種方式能夠指定第n個的最後一步*而不是總是「倒數第二(或第一,如果只有1」,例如在我的代碼示例中,也許你想將它改爲倒數第二個字,而不是第二個倒數第二個字)我請求你澄清,但你沒有在我發佈這個解決方案的時候沒有迴應,所以我沒有寫代碼來靈活處理,但是,如果這是你想要的,希望你能夠接受並修改它以適應你。基本上,它將涉及將另一個參數傳遞到repWords,並且還將涉及使用另一個全局變量用於addHtml,其中使用$cc==($count-1)

+0

感謝您的答案! ...我還沒有申請這個,但會嘗試一下,看看它是如何工作的。在「不是第一次出現」的部分,我真正想要做的是拋出一個隨機選擇,並限制它只換出n個可能選項中的一個,但理想情況下也不是第一個選項(如果有時儘管抓住第一個選項)。 ...我會修補並讓你知道它是怎麼回事。 – gtr1971

+0

好的,我已經能夠插入你的解決方案,並且我得到了不同的結果。如果一個單詞出現在內容中3次,代碼將操縱最後兩個事件,而不是第二個事件。我在這裏要做的一件事情是限制HTML替換的數量(在這種情況下,它是頁面錨點)。我想限制內容中錨點的總數不超過3個最大值。 – gtr1971

+0

感謝您的解決方案!我做了一些調整和修改以滿足其他一些要求,但是讓我有了很長的路要走。 – gtr1971