2009-09-18 6 views
18

Whats là cách tốt nhất để lấy nội dung giữa hai chuỗi, ví dụ:Lấy nội dung giữa hai chuỗi PHP

ob_start(); 
include('externalfile.html'); ## see below 
$out = ob_get_contents(); 
ob_end_clean(); 

preg_match('/{FINDME}(.|\n*)+{\/FINDME}/',$out,$matches); 
$match = $matches[0]; 

echo $match; 

## I have used .|\n* as it needs to check for new lines. Is this correct? 

## externalfile.html 

{FINDME} 
Text Here 
{/FINDME} 

Vì một số lý do, điều này dường như hoạt động ở một nơi trong mã của tôi chứ không phải một vị trí khác. Tôi đang đi về điều này một cách đúng đắn? đây có phải là cách tốt hơn không?

Cũng là bộ đệm đầu ra theo cách để thực hiện điều này hoặc file_get_contents?

Cảm ơn trước!

+0

Nếu nó hoạt động trong một số trường hợp và không phải là những trường hợp khác, bạn nên cung cấp ví dụ về thời điểm hoạt động và khi nào nó không hoạt động. – Welbog

Trả lời

35
  • Sử dụng # thay vì / để bạn không phải thoát chúng.
  • modifiers làm cho .\s cũng bao gồm dòng mới.
  • {} có chức năng khác nhau như từ n đến m lần trong {n,m}.
  • Các cơ bản

    preg_match('#\\{FINDME\\}(.+)\\{/FINDME\\}#s',$out,$matches); 
    
  • Các tiên tiến cho thẻ khác nhau vv (phong cách không phải là quá đẹp bằng javascript).

    $delimiter = '#'; 
    $startTag = '{FINDME}'; 
    $endTag = '{/FINDME}'; 
    $regex = $delimiter . preg_quote($startTag, $delimiter) 
            . '(.*?)' 
            . preg_quote($endTag, $delimiter) 
            . $delimiter 
            . 's'; 
    preg_match($regex,$out,$matches); 
    

Đặt mã này trong một hàm

  • Đối với bất kỳ tập tin mà bạn không muốn execue bất kỳ mã php hoang, bạn nên sử dụng file_get_contents. bao gồm/yêu cầu thậm chí không nên là một tùy chọn ở đó.
+2

Tôi đặt cược {FINDME} chỉ để minh họa –

39

Bạn cũng có thể sử dụng chất nền và lớp phủ cho việc này.

$startsAt = strpos($out, "{FINDME}") + strlen("{FINDME}"); 
$endsAt = strpos($out, "{/FINDME}", $startsAt); 
$result = substr($out, $startsAt, $endsAt - $startsAt); 

Bạn sẽ cần phải thêm kiểm tra lỗi để xử lý trường hợp không FINDME.

+1

Đây là cách tốt nhất để làm điều đó khi có thể –

+0

đồng ý với Cem Kalyoncu – Peter

+0

Cảm ơn bạn đã giải pháp thay thế, nó giải quyết được vấn đề của tôi. Tôi đã thực hiện một preg_match với một chuỗi lớn mà trả về một mảng trống. Giải pháp của bạn đã khắc phục được sự cố của tôi. – meenxo

1

Ngắt dòng có thể gây ra sự cố trong RegEx, hãy thử xóa hoặc thay thế bằng \ n trước khi xử lý.

-1

Cách nhanh chóng để đặt mọi thứ vào một chuỗi.

$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B"); 
$one_string = str_replace($newlines, "", html_entity_decode($content)); 
0
function getInbetweenStrings($start, $end, $str){ 
    $matches = array(); 
    $regex = "/$start([a-zA-Z0-9_]*)$end/"; 
    preg_match_all($regex, $str, $matches); 
    return $matches[1]; 
} 


$str = "C://@@[email protected]@/@@[email protected]@/@@[email protected]@"; 
$str_arr = getInbetweenStrings('@@', '@@', $str); 

print_r($str_arr); 
+0

Điều này không hoạt động. ví dụ. 'getInbetweenStrings ('bắt đầu', 'kết thúc', 'bắt đầu nhận kết thúc chuỗi này'); ' – billynoah

4

Tôi yêu hai giải pháp này

function GetBetween($content,$start,$end) 
{ 
    $r = explode($start, $content); 
    if (isset($r[1])){ 
     $r = explode($end, $r[1]); 
     return $r[0]; 
    } 
    return ''; 
} 


function get_string_between($string, $start, $end){ 
    $string = " ".$string; 
    $ini = strpos($string,$start); 
    if ($ini == 0) return ""; 
    $ini += strlen($start); 
    $len = strpos($string,$end,$ini) - $ini; 
    return substr($string,$ini,$len); 
} 

Tôi cũng làm vài tiêu chuẩn cũng như với cả hai giải pháp trên và cả hai đều được đưa ra gần như cùng một lúc. Bạn cũng có thể kiểm tra nó. Tôi đã cung cấp cho cả hai chức năng một tệp để đọc có khoảng 60000 ký tự (được xem xét với số từ của cô Word) và cả hai hàm đều dẫn đến khoảng 0,000999 giây để tìm.

$startTime = microtime(true); 
GetBetween($str, '<start>', '<end>'); 
echo "Explodin Function took: ".(microtime(true) - $startTime) . " to finish<br />"; 

$startTime = microtime(true); 
get_string_between($str, '<start>', '<end>'); 
echo "Subsring Function took: ".(microtime(true) - $startTime) . " to finish<br />"; 
+0

Điều này thật tuyệt. Nó có thể được thực hiện để làm việc để tìm thấy nhiều trận đấu? Vì vậy, trả về một mảng với tất cả các trận đấu? –

0

Đây là giải pháp PHP trả về các chuỗi được tìm thấy giữa các thẻ trong haystack. Nó hoạt động, nhưng tôi chưa thử nghiệm hiệu quả. Tôi cần điều này và được lấy cảm hứng từ câu trả lời của Adam Wright trên trang này.

Trả về mảng() chứa tất cả các chuỗi được tìm thấy giữa $ tag và $ end_symbold. $ Tag trong $ haystack hoặc FALSE nếu không có $ end_symbol. $ Tag được tìm thấy do đó không có cặp thẻ nào tồn tại trong $ haystack.

function str_between_tags($haystack, $tag, $end_symbol){ 
    $c_end_tags = substr_count($haystack, $end_symbol.$tag); 
    if(!$c_end_tags) return FALSE; 

    for($i=0; $i<$c_end_tags; $i++){ 
     $p_s = strpos($haystack, $tag, (($p_e)?$p_e+strlen($end_symbol.$tag):NULL)) + strlen($tag); 
     $p_e = strpos($haystack, $end_symbol.$tag, $p_s); 
     $result[] = substr($haystack, $p_s, $p_e - $p_s); 
    } 
    return $result; 
}