2012-02-22 199 views
3

我有一個HTML標籤一個簡單的文本,例如:替換文本忽略HTML標籤

Once <u>the</u> activity <a href="#">reaches</a> the resumed state, you can freely add and remove fragments to the activity. Thus, <i>only</i> while the activity is in the resumed state can the <b>lifecycle</b> of a <hr/> fragment change independently. 

我需要更換這個文本的某些部分忽視了它的HTML標籤,當我這樣做替換,例如該字符串 - Thus, <i>only</i> while我需要用我的字符串Hello, <i>its only</i> while來替換。要被替換的文本和字符串是動態的。我需要您的幫助與我的preg_replace模式

$text = '<b>Some html</b> tags with <u>and</u> there are a lot of tags <i>in</i> this text'; 

$arrayKeys= array('Some html' => 'My html', 'and there' => 'is there', 'in this text' => 'in this code'); 

foreach ($arrayKeys as $key => $value) 
    $text = preg_replace('...$key...', '...$value...', $text); 

echo $text; // output should be: <b>My html</b> tags with <u>is</u> there are a lot of tags <i>in</i> this code'; 

請幫我找到解決辦法。謝謝

+1

所提供的例子,我不相信正則表達式可以做你想做的,因爲你沒有一個具體的一套規則,似乎你的要求改變與你提供的每個不同的例子。 – qJake 2012-02-22 23:01:55

+0

好吧正則表達式不能..也許有任何其他工具?...問題是,用戶(網站管理員)輸入數據被替換,數組是動態的 – pleerock 2012-02-22 23:10:44

+0

可能無法完成。除非你能澄清,如果字符串是「你好世界再次」。我想用「你好來自地球」來代替「你好世界」。輸出是什麼? – iWantSimpleLife 2012-02-23 01:13:55

回答

0

在這裏,我們走了。這段代碼應該可以工作,假設你僅尊重兩個約束:

  • 模式和替換必須具有相同的字數。 (邏輯,因爲你想保持位置)
  • 你不能圍繞標籤分​​詞。 (<b>赫爾</B > LO世界將無法正常工作。)

但是,如果這些都得到尊重,這應該只是罰款!

<?php 
    // Splits a string in parts delimited with the sequence. 
    // '<b>Hey</b> you' becomes '~-=<b>~-=Hey~-=</b>~-= you' that make us get 
    // array ("<b>", "Hey" " you") 
    function getTextArray ($text, $special) { 
     $text = preg_replace ('#(<.*>)#isU', $special . '$1' . $special, $text); // Adding spaces to make explode work fine. 

     return preg_split ('#' . $special . '#', $text, -1, PREG_SPLIT_NO_EMPTY); 
    } 
     $text = " 
    <html> 
     <div> 
      <p> 
       <b>Hey</b> you ! No, you don't have <em>to</em> go! 
      </p> 
     </div> 
    </html>"; 

    $replacement = array (
     "Hey you" => "Bye me", 
     "have to" => "need to", 
     "to go" => "to run"); 

    // This is a special sequence that you must be sure to find nowhere in your code. It is used to split sequences, and will disappear. 
    $special = '~-='; 

    $text_array = getTextArray ($text, $special); 

    // $restore is the array that will finally contain the result. 
    // Now we're only storing the tags. 
    // We'll be story the text later. 
    // 
    // $clean_text is the text without the tags, but with the special sequence instead. 
    $restore = array(); 
    for ($i = 0; $i < sizeof ($text_array); $i++) { 
     $str = $text_array[$i]; 

     if (preg_match('#<.+>#', $str)) { 
      $restore[$i] = $str; 
      $clean_text .= $special; 
     } 

     else { 
      $clean_text .= $str; 
     } 
    } 

    // Here comes the tricky part. 
    // We wanna keep the position of each part of the text so the tags don't 
    // move after. 
    // So we're making the regex look like (~-=)*Hey(~-=)* you(~-=)* 
    // And the replacement look like $1Bye$2 me $3. 
    // So that we keep the separators at the right place. 
    foreach ($replacement as $regex => $newstr) { 
     $regex_array = explode (' ', $regex); 
     $regex = '(' . $special . '*)' . implode ('(' . $special . '*) ', $regex_array) . '(' . $special . '*)'; 

     $newstr_array = explode (' ', $newstr); 
     $newstr = "$1"; 

     for ($i = 0; $i < count ($regex_array) - 1; $i++) { 
      $newstr .= $newstr_array[$i] . '$' . ($i + 2) . ' '; 
     } 
     $newstr .= $newstr_array[count($regex_array) - 1] . '$' . (count ($regex_array) + 1); 

     $clean_text = preg_replace ('#' . $regex . '#isU', $newstr, $clean_text); 
    } 

    // Here we re-split one last time. 
    $clean_text_array = preg_split ('#' . $special . '#', $clean_text, -1, PREG_SPLIT_NO_EMPTY); 

    // And we merge with $restore. 
    for ($i = 0, $j = 0; $i < count ($text_array); $i++) { 
     if (!isset($restore[$i])) { 
      $restore[$i] = $clean_text_array[$j]; 
      $j++; 
     } 
    } 

    // Now we reorder everything, and make it go back to a string. 
    ksort ($restore); 
    $result = implode ($restore); 

    echo $result; 
?> 

將輸出再見我!不,你不需要就跑!

[編輯]現在支持自定義模式,它允許避免添加無用的空間。

+0

我看到HTML的全局變量和正則表達式。因此,我的downvote。正則表達式的HTML幾乎總是可以被打破,這也不例外。 – 2013-05-28 08:58:03

+0

嗡嗡聲,問題標籤是什麼?這不是因爲一種習慣不被告知它不能實現。 – Jerska 2013-05-28 09:02:18

+1

由於我們在這場辯論中,PHP在許多方面是一種可怕的語言,但它的一些功能讓我喜歡它。根據你的說法,我應該退出PHP編程嗎? – Jerska 2013-05-28 09:04:51

1

基本上我們將使用正則表達式構建動態的匹配和模式數組。此代碼只能匹配最初要求的代碼,但您應該能夠了解如何從我拼寫完成的方式編輯代碼。我們捕捉一個打開或關閉的標籤和空白作爲passthru變量並替換它周圍的文本。這是基於兩個和三個字組合設置的。

<?php 

    $text = '<b>Some html</b> tags with <u>and</u> there are a lot of tags <i>in</i> this text'; 

    $arrayKeys= array(
    'Some html' => 'My html', 
    'and there' => 'is there', 
    'in this text' =>'in this code'); 


    function make_pattern($string){ 
     $patterns = array(
         '!(\w+)!i', 
         '#^#', 
         '! !', 
         '#$#'); 
     $replacements = array(
         "($1)", 
         '!', 
       //This next line is where we capture the possible tag or 
       //whitespace so we can ignore it and pass it through. 
         '(\s?<?/?[^>]*>?\s?)', 
         '!i'); 
     $new_string = preg_replace($patterns,$replacements,$string); 
     return $new_string; 
    } 

    function make_replacement($replacement){ 
     $patterns = array(
         '!^(\w+)(\s+)(\w+)(\s+)(\w+)$!', 
         '!^(\w+)(\s+)(\w+)$!'); 
     $replacements = array(
         '$1\$2$3\$4$5', 
         '$1\$2$3'); 
     $new_replacement = preg_replace($patterns,$replacements,$replacement); 
     return $new_replacement; 
    } 


    foreach ($arrayKeys as $key => $value){ 
     $new_Patterns[] = make_pattern($key); 
     $new_Replacements[] = make_replacement($value); 
    } 

    //For debugging 
    //print_r($new_Patterns); 
    //print_r($new_Replacements); 

    $new_text = preg_replace($new_Patterns,$new_Replacements,$text); 

    echo $new_text."\n"; 
    echo $text; 


?> 

輸出

<b>My html</b> tags with <u>is</u> there are a lot of tags <i>in</i> this code 
<b>Some html</b> tags with <u>and</u> there are a lot of tags <i>in</i> this text