2011-10-08 137 views
3

我目前正在嘗試將標記添加到使用PHP的CMS。PHP RegExp替換

用戶可以輸入(在WYSIWYG編輯器中)一個字符串,如[my_include.php]。我們願與這種格式來提取任何東西,並把它變成一個包括以下格式:

include('my_include.php');

任何人都可以協助撰寫的正則表達式和提取過程中允許這樣做?理想情況下,我想將它們全部提取到單個數組中,以便我們可以在將其解析爲include();之前提供一些檢查?

謝謝!

+0

您使用的是哪種CMS? – Olli

+0

這是一個定製的系統。 – BenM

回答

3
preg_replace('~\[([^\]]+)\]~', 'include "\\1";', $str); 

工作樣本:http://ideone.com/zkwX7

+0

@BenM爲了將來的參考,請在原始問題中編輯附加代碼,而不是評論。這樣,它的格式很好,可以理解,所以我們可以幫助你更好。 – Bojangles

0

使用preg_match_all(),你可以這樣做:

$matches = array(); 

// If we've found any matches, do stuff with them 
if(preg_match_all("/\[.+\.php\]/i", $input, $matches)) 
{ 
    foreach($matches as $match) 
    { 
     // Any validation code goes here 

     include_once("/path/to/" . $match); 
    } 
} 

這裏使用的正則表達式是\[.+\.php\]。這將匹配任何*.php字符串,因此例如,如果用戶鍵入[hello],它將不匹配。

2

你可能想要使用preg_match_all(),在循環中運行結果並替換你找到的任何東西。可能會比以下回調方案快一些,但如果使用PREG_OFFSET_CAPUTRE和substr_replace()會更棘手。

<?php 

function handle_replace_thingie($matches) { 
    // build a file path 
    $file = '/path/to/' . trim($matches[1]); 

    // do some sanity checks, like file_exists, file-location (not that someone includes /etc/passwd or something) 
    // check realpath(), file_exists() 
    // limit the readable files to certain directories 
    if (false) { 
    return $matches[0]; // return original, no replacement 
    } 

    // assuming the include file outputs its stuff we need to capture it with an output buffer 
    ob_start(); 
    // execute the include 
    include $file; 
    // grab the buffer's contents 
    $res = ob_get_contents(); 
    ob_end_clean(); 
    // return the contents to replace the original [foo.php] 
    return $res; 
} 

$string = "hello world, [my_include.php] and [foo-bar.php] should be replaced"; 
$string = preg_replace_callback('#\[([^\[]+)\]#', 'handle_replace_thingie', $string); 
echo $string, "\n"; 

?>