วิธีรับ substring ระหว่างสองสายใน PHP?


142

ฉันต้องการฟังก์ชั่นที่คืนค่าสตริงย่อยระหว่างสองคำ (หรือสองตัวอักษร) ฉันสงสัยว่ามีฟังก์ชั่น php หรือไม่ ฉันไม่ต้องการคิดเกี่ยวกับ regex (ดีฉันสามารถทำได้ แต่ไม่คิดว่ามันเป็นวิธีที่ดีที่สุดที่จะไป) การคิดstrposและsubstrหน้าที่ นี่คือตัวอย่าง:

$string = "foo I wanna a cake foo";

เราเรียกฟังก์ชั่น: $substring = getInnerSubstring($string,"foo");
มันคืน: "ฉันอยากได้เค้ก"

ขอบคุณล่วงหน้า.

Update: อืมจนถึงตอนนี้ฉันสามารถรับสายย่อยสองคำได้ในสตริงเดียวคุณอนุญาตให้ฉันออกไปอีกหน่อยและถามว่าฉันจะขยายการใช้getInnerSubstring($str,$delim)เพื่อรับสายใด ๆ ที่อยู่ระหว่างค่า delim หรือไม่ ตัวอย่าง:

$string =" foo I like php foo, but foo I also like asp foo, foo I feel hero  foo";

{"I like php", "I also like asp", "I feel hero"}ฉันได้รับอาร์เรย์เช่น


2
หากคุณใช้ Laravel อยู่แล้ว\Illuminate\Support\Str::between('This is my name', 'This', 'name');สะดวกสบาย laravel.com/docs/7.x/helpers#method-str-between
Ryan

คำตอบ:


324

หากสตริงแตกต่างกัน (เช่น: [foo] & [/ foo]) ลองดูที่โพสต์นี้จาก Justin Cook ฉันคัดลอกรหัสของเขาด้านล่าง:

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);
}

$fullstring = 'this is my [tag]dog[/tag]';
$parsed = get_string_between($fullstring, '[tag]', '[/tag]');

echo $parsed; // (result = dog)

7
func นี้ได้รับการแก้ไขเพื่อให้ครอบคลุมตั้งแต่เริ่มต้นและสิ้นสุด <code> ฟังก์ชั่น string_between ($ string, $ start, $ end, $ inclusive = false) {$ string = "". $ string; $ ini = strpos ($ string, $ start); ถ้า ($ ini == 0) ส่งคืน ""; if (! $ inclusive) $ ini + = strlen ($ start); $ len = strpos ($ string, $ end, $ ini) - $ ini; ถ้า (รวม $) $ len + = strlen ($ end); ส่งคืน substr ($ string, $ ini, $ len); } </code>
Henry

2
เป็นไปได้ไหมที่จะขยายฟังก์ชั่นนี้เพื่อให้มันสามารถคืนสองสตริงได้? สมมติว่าฉันมี $ fullstring ของ "[tag] Dogs [/ tag] และ [tag] cats [/ tag]" และฉันต้องการอาร์เรย์กลับซึ่งมี "Dogs" และ "cats"
Leonard Schuetz

1
@LeonardSchuetz - ลองคำตอบนี้แล้ว
leymannx

"[tag] Dogs [/ tag] และ [tag] cats [/ tag]" ยังไม่ได้รับคำตอบ วิธีรับ "สุนัข" และ "แมว" ในรูปแบบอาร์เรย์ได้อย่างไร โปรดให้คำแนะนำ.
Romnick Susa

1
มีคนตอบคำถามของฉัน! คุณสามารถเยี่ยมชมstackoverflow.com/questions/35168463/
Romnick Susa

80

นิพจน์ทั่วไปคือหนทางที่จะไป:

$str = 'before-str-after';
if (preg_match('/before-(.*?)-after/', $str, $match) == 1) {
    echo $match[1];
}

onlinePhp


1
มันสมบูรณ์แบบ ขอบคุณ!
Kyle K

มันใช้งานได้ดี! และสำหรับคนที่ไม่คุ้นเคยกับ regEx เพียงเพิ่ม "\" เพื่อหลีกเลี่ยงอักขระพิเศษ: sandbox.onlinephpfunctions.com/code/…
JCarlosR

หากคุณต้องการหลายเหตุการณ์ลองทำสิ่งนี้หลาย
user1424074

22
function getBetween($string, $start = "", $end = ""){
    if (strpos($string, $start)) { // required if $start not exist in $string
        $startCharCount = strpos($string, $start) + strlen($start);
        $firstSubStr = substr($string, $startCharCount, strlen($string));
        $endCharCount = strpos($firstSubStr, $end);
        if ($endCharCount == 0) {
            $endCharCount = strlen($firstSubStr);
        }
        return substr($firstSubStr, 0, $endCharCount);
    } else {
        return '';
    }
}

ตัวอย่างการใช้งาน:

echo getBetween("abc","a","c"); // returns: 'b'

echo getBetween("hello","h","o"); // returns: 'ell'

echo getBetween("World","a","r"); // returns: ''

5
BTW ย่อหน้า "ตัวอย่างการใช้งาน" ของคุณผิด ข้อโต้แย้งนั้นอยู่ในลำดับที่ผิดทั้งหมด
นั้น

15
function getInnerSubstring($string,$delim){
    // "foo a foo" becomes: array(""," a ","")
    $string = explode($delim, $string, 3); // also, we only need 2 items at most
    // we check whether the 2nd is set and return it, otherwise we return an empty string
    return isset($string[1]) ? $string[1] : '';
}

ตัวอย่างการใช้งาน:

var_dump(getInnerSubstring('foo Hello world foo','foo'));
// prints: string(13) " Hello world "

trimหากคุณต้องการที่จะลบช่องว่างรอบการใช้งาน ตัวอย่าง:

var_dump(trim(getInnerSubstring('foo Hello world foo','foo')));
// prints: string(11) "Hello world"

1
นี่เป็นระเบียบเพราะมันเป็นซับเดียว แต่น่าเสียดายที่มัน จำกัด อยู่ที่การมีตัวคั่นเฉพาะเช่นถ้าคุณต้องการซับสตริงระหว่าง "foo" และ "bar" คุณจะต้องใช้กลยุทธ์อื่น
mastazi

13
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://@@ad_custom_attr1@@/@@upn@@/@@samaccountname@@";
$str_arr = getInbetweenStrings('@@', '@@', $str);

print_r($str_arr);

3
อย่าลืมที่จะหลบหนี "/" อย่าง "\ /" เมื่อเป็นตัวแปร $ start หรือ $ end
LubošRemplík

10

ใช้ฟังก์ชั่น strstr php สองครั้ง

$value = "This is a great day to be alive";
$value = strstr($value, "is"); //gets all text from needle on
$value = strstr($value, "be", true); //gets all text before needle
echo $value;

เอาท์พุท: "is a great day to"


8

ฉันชอบคำตอบปกติ แต่ไม่มีคนอื่นที่เหมาะกับฉัน

หากคุณรู้ว่ามีเพียง 1 ผลคุณสามารถใช้สิ่งต่อไปนี้:

$between = preg_replace('/(.*)BEFORE(.*)AFTER(.*)/sm', '\2', $string);

เปลี่ยนก่อนและหลังเป็นตัวคั่นที่ต้องการ

โปรดทราบว่าฟังก์ชั่นนี้จะคืนค่าสตริงทั้งหมดในกรณีที่ไม่มีสิ่งใดที่ตรงกัน

โซลูชันนี้เป็นแบบหลายบรรทัด แต่คุณสามารถเล่นกับตัวปรับเปลี่ยนได้ตามความต้องการของคุณ


7

ไม่ใช่ php pro แต่ฉันเพิ่งวิ่งเข้าไปในกำแพงนี้ด้วยและนี่คือสิ่งที่ฉันมาด้วย

function tag_contents($string, $tag_open, $tag_close){
   foreach (explode($tag_open, $string) as $key => $value) {
       if(strpos($value, $tag_close) !== FALSE){
            $result[] = substr($value, 0, strpos($value, $tag_close));;
       }
   }
   return $result;
}

$string = "i love cute animals, like [animal]cat[/animal],
           [animal]dog[/animal] and [animal]panda[/animal]!!!";

echo "<pre>";
print_r(tag_contents($string , "[animal]" , "[/animal]"));
echo "</pre>";

//result
Array
(
    [0] => cat
    [1] => dog
    [2] => panda
)

6

หากคุณใช้fooเป็นตัวคั่นให้ดูที่explode()


ใช่เราสามารถได้ผลลัพธ์ที่ต้องการโดยใช้ดัชนีที่ 1 ของอาร์เรย์ที่ระเบิด (ไม่ใช่ศูนย์)
captain_a

6
<?php
  function getBetween($content,$start,$end){
    $r = explode($start, $content);
    if (isset($r[1])){
        $r = explode($end, $r[1]);
        return $r[0];
    }
    return '';
  }
?>

ตัวอย่าง:

<?php 
  $content = "Try to find the guy in the middle with this function!";
  $start = "Try to find ";
  $end = " with this function!";
  $output = getBetween($content,$start,$end);
  echo $output;
?>

สิ่งนี้จะส่งกลับ "คนกลาง"


3

หากคุณมีการเกิดซ้ำหลายครั้งจากสตริงเดียวและคุณมีรูปแบบ [start] และ [\ end] ที่แตกต่างกัน นี่คือฟังก์ชันที่เอาต์พุตอาร์เรย์

function get_string_between($string, $start, $end){
    $split_string       = explode($end,$string);
    foreach($split_string as $data) {
         $str_pos       = strpos($data,$start);
         $last_pos      = strlen($data);
         $capture_len   = $last_pos - $str_pos;
         $return[]      = substr($data,$str_pos+1,$capture_len);
    }
    return $return;
}

3

นี่คือฟังก์ชั่น

function getInnerSubstring($string, $boundstring, $trimit=false) {
    $res = false;
    $bstart = strpos($string, $boundstring);
    if ($bstart >= 0) {
        $bend = strrpos($string, $boundstring);
        if ($bend >= 0 && $bend > $bstart)
            $res = substr($string, $bstart+strlen($boundstring), $bend-$bstart-strlen($boundstring));
    }
    return $trimit ? trim($res) : $res;
}

ใช้มันเหมือน

$string = "foo I wanna a cake foo";
$substring = getInnerSubstring($string, "foo");

echo $substring;

เอาท์พุท (โปรดทราบว่ามันจะส่งคืนช่องว่างด้านหน้าและที่และของสตริงของคุณถ้ามี)

ฉันอยากได้เค้ก

หากคุณต้องการตัดแต่งผลการใช้งานฟังก์ชั่นเช่น

$substring = getInnerSubstring($string, "foo", true);

ส่งผลให้มีฟังก์ชั่นนี้จะกลับเท็จถ้า$boundstringไม่พบใน$stringหรือถ้า$boundstringมีอยู่เพียงครั้งเดียวใน$stringมิฉะนั้นก็จะส่งกลับ substring ระหว่างเกิดขึ้นครั้งแรกและครั้งสุดท้ายของใน$boundstring$string


อ้างอิง


คุณใช้ if-clause โดยไม่มีเครื่องหมายวงเล็บ แต่คุณอาจรู้ว่ามันเป็นความคิดที่ไม่ดีใช่ไหม
xmoex

@xmoex IFประโยคที่คุณพูดถึงคืออะไร? บางทีฉันอาจพิมพ์ผิด แต่พูดตามตรงฉันไม่เห็นอะไรแปลก ๆ ในตอนนี้ ทั้งสองIFฉันใช้ในการทำงานข้างต้นมีวงเล็บที่เหมาะสมสภาพโดยรอบ ครั้งแรกIFยังมีวงเล็บปีกกา (วงเล็บปีกกา) ที่ล้อมรอบบล็อก 2 บรรทัด 2 IFไม่จำเป็นต้อง 'em เพราะมันเป็นรหัสบรรทัดเดียว ฉันกำลังคิดถึงอะไร
Wh1T3h4Ck5

ฉันกำลังพูดถึงบรรทัดเดียว ฉันคิดว่าบรรณาธิการของโพสต์ของคุณลบ แต่แล้วฉันก็เห็นว่ามันไม่ได้อยู่ที่นั่นตั้งแต่แรก imvho นี่เป็นแหล่งที่มาทั่วไปของบางครั้งยากที่จะหาข้อบกพร่องถ้าคุณเปลี่ยนรหัสในอนาคต
xmoex

@xmoex ไม่เห็นด้วยอย่างมาก หลังจากผ่านไปเกือบ 20 ปีในการทำธุรกิจฉันสามารถพูดได้ว่าเครื่องมือจัดฟันนั้นเป็นสาเหตุของข้อบกพร่องที่หายากมาก การล้อมรอบบรรทัดเดียวด้วยเครื่องหมายปีกกาน่าเกลียด (เรื่องของความเห็น) และทำให้โค้ดใหญ่ขึ้น (แท้ที่จริง) ใน บริษัท ส่วนใหญ่จำเป็นต้องลบการจัดฟันที่ไม่จำเป็นในการเติมโค้ดให้สมบูรณ์ จริงอาจเป็นเรื่องยากที่จะสังเกตเห็นในระหว่างการดีบักสำหรับผู้ใช้ที่ไม่มีประสบการณ์ แต่นั่นไม่ใช่ปัญหาระดับโลกเพียงก้าวไปสู่เส้นทางการเรียนรู้ของพวกเขา ส่วนตัวผมไม่เคยมีปัญหากับเครื่องมือจัดฟันแม้แต่ในกรณีที่มีการทำรังแบบซับซ้อน
Wh1T3h4Ck5

@ Wh1T3h4Ck5 ฉันเคารพในความคิดเห็นและประสบการณ์ของคุณ แต่ฉันไม่เชื่อเลย เครื่องมือจัดฟันไม่ทำให้โค้ดใหญ่ขึ้นจากมุมมองของระบบ มันขยายขนาดไฟล์ แต่คอมไพเลอร์ดูแลอะไร? และถ้าใช้ js คุณอาจจะรหัสน่าเกลียดโดยอัตโนมัติก่อนที่จะมีชีวิตอยู่ ฉันคิดว่าการใช้เครื่องมือจัดฟันมักเจ็บน้อยกว่าและละเว้น "บางครั้ง" ...
xmoex

3

การปรับปรุงคำตอบของ Alejandro คุณสามารถออกจาก$startหรือ$endข้อโต้แย้งที่ว่างเปล่าและมันจะใช้เริ่มต้นหรือสิ้นสุดของสตริง

echo get_string_between("Hello my name is bob", "my", ""); //output: " name is bob"

private function get_string_between($string, $start, $end){ // Get
    if($start != ''){ //If $start is empty, use start of the string
        $string = ' ' . $string;
        $ini = strpos($string, $start);
        if ($ini == 0) return '';
        $ini += strlen($start);
    }
    else{
        $ini = 0;
    }

    if ($end == '') { //If $end is blank, use end of string
        return substr($string, $ini);
    }
    else{
        $len = strpos($string, $end, $ini) - $ini; //Work out length of string
        return substr($string, $ini, $len);
    }
}

1

ใช้:

<?php

$str = "...server daemon started with pid=6849 (parent=6848).";
$from = "pid=";
$to = "(";

echo getStringBetween($str,$from,$to);

function getStringBetween($str,$from,$to)
{
    $sub = substr($str, strpos($str,$from)+strlen($from),strlen($str));
    return substr($sub,0,strpos($sub,$to));
}

?>

1

โค้ดที่ได้รับการปรับปรุงเล็กน้อยจาก GarciaWebDev และ Henry Wang หากมีการกำหนด $ start หรือ $ end ที่ว่างเปล่าฟังก์ชันจะส่งคืนค่าจากจุดเริ่มต้นหรือจุดสิ้นสุดของ $ string นอกจากนี้ยังมีตัวเลือกรวมไม่ว่าเราต้องการรวมผลการค้นหาหรือไม่:

function get_string_between ($string, $start, $end, $inclusive = false){
    $string = " ".$string;

    if ($start == "") { $ini = 0; }
    else { $ini = strpos($string, $start); }

    if ($end == "") { $len = strlen($string); }
    else { $len = strpos($string, $end, $ini) - $ini;}

    if (!$inclusive) { $ini += strlen($start); }
    else { $len += strlen($end); }

    return substr($string, $ini, $len);
}

1

ฉันต้องเพิ่มบางอย่างในโพสต์ของ Julius Tilvikas ฉันหาวิธีแก้ปัญหาเช่นนี้เขาอธิบายไว้ในโพสต์ของเขา แต่ฉันคิดว่ามีข้อผิดพลาด ฉันไม่เข้าใจสตริงระหว่างสองสตริงจริง ๆ ฉันยังได้มากขึ้นด้วยโซลูชันนี้เพราะฉันต้องย่อความยาวของสตริงเริ่มต้น เมื่อทำสิ่งนี้ฉันจะได้รับสตริงระหว่างสองสตริง

นี่คือการเปลี่ยนแปลงวิธีแก้ปัญหาของฉัน:

function get_string_between ($string, $start, $end, $inclusive = false){
    $string = " ".$string;

    if ($start == "") { $ini = 0; }
    else { $ini = strpos($string, $start); }

    if ($end == "") { $len = strlen($string); }
    else { $len = strpos($string, $end, $ini) - $ini - strlen($start);}

    if (!$inclusive) { $ini += strlen($start); }
    else { $len += strlen($end); }

    return substr($string, $ini, $len);
}

Greetz

V


1

ลองสิ่งนี้มันใช้ได้ผลกับฉันรับข้อมูลระหว่างคำทดสอบ

$str = "Xdata test HD01 test 1data";  
$result = explode('test',$str);   
print_r($result);
echo $result[1];

1

ในstrposสไตล์ของ PHP สิ่งนี้จะกลับมาfalseหากเครื่องหมายเริ่มต้นsmหรือเครื่องหมายสิ้นสุดemไม่พบ

ผลลัพธ์นี้ ( false) แตกต่างกันจากสตริงว่างนั่นคือสิ่งที่คุณจะได้รับหากไม่มีอะไรระหว่างเครื่องหมายเริ่มต้นและสิ้นสุด

function between( $str, $sm, $em )
{
    $s = strpos( $str, $sm );
    if( $s === false ) return false;
    $s += strlen( $sm );
    $e = strpos( $str, $em, $s );
    if( $e === false ) return false;
    return substr( $str, $s, $e - $s );
}

ฟังก์ชั่นจะกลับเฉพาะการแข่งขันครั้งแรก

เห็นได้ชัดว่ามันคุ้มค่าที่จะกล่าวถึงฟังก์ชั่นแรก smแล้วก่อนemก่อน

ซึ่งหมายความว่าคุณอาจไม่ได้รับผลที่ต้องการ / พฤติกรรมถ้าจะต้องมีการสืบค้นก่อนแล้วสตริงจะต้องมีการแยกวิเคราะห์ย้อนหลังในการค้นหาemsm


1

นี่คือฟังก์ชั่นที่ฉันใช้สำหรับสิ่งนี้ ฉันรวมสองคำตอบในฟังก์ชันเดียวสำหรับตัวคั่นเดียวหรือหลายตัว

function getStringBetweenDelimiters($p_string, $p_from, $p_to, $p_multiple=false){
    //checking for valid main string  
    if (strlen($p_string) > 0) {
        //checking for multiple strings 
        if ($p_multiple) {
            // getting list of results by end delimiter
            $result_list = explode($p_to, $p_string);
            //looping through result list array 
            foreach ( $result_list AS $rlkey => $rlrow) {
                // getting result start position
                $result_start_pos   = strpos($rlrow, $p_from);
                // calculating result length
                $result_len         =  strlen($rlrow) - $result_start_pos;

                // return only valid rows
                if ($result_start_pos > 0) {
                    // cleanying result string + removing $p_from text from result
                    $result[] =   substr($rlrow, $result_start_pos + strlen($p_from), $result_len);                 
                }// end if 
            } // end foreach 

        // if single string
        } else {
            // result start point + removing $p_from text from result
            $result_start_pos   = strpos($p_string, $p_from) + strlen($p_from);
            // lenght of result string
            $result_length      = strpos($p_string, $p_to, $result_start_pos);
            // cleaning result string
            $result             = substr($p_string, $result_start_pos+1, $result_length );
        } // end if else 
    // if empty main string
    } else {
        $result = false;
    } // end if else 

    return $result;


} // end func. get string between

สำหรับการใช้งานง่าย (คืนสอง):

$result = getStringBetweenDelimiters(" one two three ", 'one', 'three');

สำหรับการทำให้แต่ละแถวในตารางเป็นอาร์เรย์ผลลัพธ์:

$result = getStringBetweenDelimiters($table, '<tr>', '</tr>', true);

1

ฉันใช้

if (count(explode("<TAG>", $input))>1){
      $content = explode("</TAG>",explode("<TAG>", $input)[1])[0];
}else{
      $content = "";
}

คำบรรยาย <TAG> สำหรับตัวคั่นที่คุณต้องการ


1

ฉบับแก้ไขของสิ่งที่ Alejandro García Iglesias ใส่

สิ่งนี้ช่วยให้คุณสามารถเลือกตำแหน่งเฉพาะของสตริงที่คุณต้องการรับตามจำนวนครั้งที่พบผลลัพธ์

function get_string_between_pos($string, $start, $end, $pos){
    $cPos = 0;
    $ini = 0;
    $result = '';
    for($i = 0; $i < $pos; $i++){
      $ini = strpos($string, $start, $cPos);
      if ($ini == 0) return '';
      $ini += strlen($start);
      $len = strpos($string, $end, $ini) - $ini;
      $result = substr($string, $ini, $len);
      $cPos = $ini + $len;
    }
    return $result;
  }

การใช้งาน:

$text = 'string has start test 1 end and start test 2 end and start test 3 end to print';

//get $result = "test 1"
$result = $this->get_string_between_pos($text, 'start', 'end', 1);

//get $result = "test 2"
$result = $this->get_string_between_pos($text, 'start', 'end', 2);

//get $result = "test 3"
$result = $this->get_string_between_pos($text, 'start', 'end', 3);

strposมีอินพุตเพิ่มเติมเพิ่มเติมเพื่อเริ่มการค้นหาที่จุดใดจุดหนึ่ง ดังนั้นฉันเก็บตำแหน่งก่อนหน้าใน $ cPos ดังนั้นเมื่อ for loop ตรวจสอบอีกครั้งมันเริ่มต้นที่จุดที่เหลือ


1

คำตอบส่วนใหญ่ที่นี่ไม่ตอบส่วนที่แก้ไขฉันเดาว่ามันถูกเพิ่มก่อนหน้านี้ มันสามารถทำได้ด้วย regex เป็นหนึ่งคำตอบที่กล่าวถึง ฉันมีวิธีการที่แตกต่างกัน


ฟังก์ชันนี้ค้นหา $ string และค้นหาสตริงแรกระหว่าง $ start และ $ end string เริ่มต้นที่ตำแหน่ง $ offset จากนั้นอัปเดตตำแหน่ง $ offset ให้ชี้ไปที่จุดเริ่มต้นของผลลัพธ์ ถ้า $ includeDelimiters เป็นจริงมันจะรวมตัวคั่นในผลลัพธ์

หากไม่พบสตริง $ start หรือ $ end ก็จะส่งคืนค่าว่าง มันจะส่งกลับค่า null ถ้า $ string, $ start หรือ $ end เป็นสตริงว่าง

function str_between(string $string, string $start, string $end, bool $includeDelimiters = false, int &$offset = 0): ?string
{
    if ($string === '' || $start === '' || $end === '') return null;

    $startLength = strlen($start);
    $endLength = strlen($end);

    $startPos = strpos($string, $start, $offset);
    if ($startPos === false) return null;

    $endPos = strpos($string, $end, $startPos + $startLength);
    if ($endPos === false) return null;

    $length = $endPos - $startPos + ($includeDelimiters ? $endLength : -$startLength);
    if (!$length) return '';

    $offset = $startPos + ($includeDelimiters ? 0 : $startLength);

    $result = substr($string, $offset, $length);

    return ($result !== false ? $result : null);
}

ฟังก์ชันต่อไปนี้ค้นหาสตริงทั้งหมดที่อยู่ระหว่างสองสตริง (ไม่ทับซ้อนกัน) มันต้องการฟังก์ชั่นก่อนหน้าและข้อโต้แย้งเหมือนกัน หลังจากการดำเนินการ $ offset ชี้ไปที่จุดเริ่มต้นของสตริงผลลัพธ์ที่พบล่าสุด

function str_between_all(string $string, string $start, string $end, bool $includeDelimiters = false, int &$offset = 0): ?array
{
    $strings = [];
    $length = strlen($string);

    while ($offset < $length)
    {
        $found = str_between($string, $start, $end, $includeDelimiters, $offset);
        if ($found === null) break;

        $strings[] = $found;
        $offset += strlen($includeDelimiters ? $found : $start . $found . $end); // move offset to the end of the newfound string
    }

    return $strings;
}

ตัวอย่าง:

str_between_all('foo 1 bar 2 foo 3 bar', 'foo', 'bar')[' 1 ', ' 3 ']จะช่วยให้

str_between_all('foo 1 bar 2', 'foo', 'bar')[' 1 ']จะช่วยให้

str_between_all('foo 1 foo 2 foo 3 foo', 'foo', 'foo')[' 1 ', ' 3 ']จะช่วยให้

str_between_all('foo 1 bar', 'foo', 'foo')[]จะช่วยให้


0

ใช้:

function getdatabetween($string, $start, $end){
    $sp = strpos($string, $start)+strlen($start);
    $ep = strpos($string, $end)-strlen($start);
    $data = trim(substr($string, $sp, $ep));
    return trim($data);
}
$dt = "Find string between two strings in PHP";
echo getdatabetween($dt, 'Find', 'in PHP');

0

ฉันมีปัญหาบางอย่างกับฟังก์ชั่น get_string_between () ที่ใช้ที่นี่ ดังนั้นฉันจึงมาพร้อมกับเวอร์ชันของฉันเอง บางทีมันอาจช่วยคนในกรณีเดียวกับฉัน

protected function string_between($string, $start, $end, $inclusive = false) { 
   $fragments = explode($start, $string, 2);
   if (isset($fragments[1])) {
      $fragments = explode($end, $fragments[1], 2);
      if ($inclusive) {
         return $start.$fragments[0].$end;
      } else {
         return $fragments[0];
      }
   }
   return false;
}

0

เขียนย้อนเวลากลับพบว่ามันมีประโยชน์มากสำหรับแอพพลิเคชั่นที่หลากหลาย

<?php

// substr_getbykeys() - Returns everything in a source string that exists between the first occurance of each of the two key substrings
//          - only returns first match, and can be used in loops to iterate through large datasets
//          - arg 1 is the first substring to look for
//          - arg 2 is the second substring to look for
//          - arg 3 is the source string the search is performed on.
//          - arg 4 is boolean and allows you to determine if returned result should include the search keys.
//          - arg 5 is boolean and can be used to determine whether search should be case-sensative or not.
//

function substr_getbykeys($key1, $key2, $source, $returnkeys, $casematters) {
    if ($casematters === true) {
        $start = strpos($source, $key1);
        $end = strpos($source, $key2);
    } else {
        $start = stripos($source, $key1);
        $end = stripos($source, $key2);
    }
    if ($start === false || $end === false) { return false; }
    if ($start > $end) {
        $temp = $start;
        $start = $end;
        $end = $temp;
    }
    if ( $returnkeys === true) {
        $length = ($end + strlen($key2)) - $start;
    } else {
        $start = $start + strlen($key1);
        $length = $end - $start;
    }
    return substr($source, $start, $length);
}

// substr_delbykeys() - Returns a copy of source string with everything between the first occurance of both key substrings removed
//          - only returns first match, and can be used in loops to iterate through large datasets
//          - arg 1 is the first key substring to look for
//          - arg 2 is the second key substring to look for
//          - arg 3 is the source string the search is performed on.
//          - arg 4 is boolean and allows you to determine if returned result should include the search keys.
//          - arg 5 is boolean and can be used to determine whether search should be case-sensative or not.
//

function substr_delbykeys($key1, $key2, $source, $returnkeys, $casematters) {
    if ($casematters === true) {
        $start = strpos($source, $key1);
        $end = strpos($source, $key2);
    } else {
        $start = stripos($source, $key1);
        $end = stripos($source, $key2);
    }
    if ($start === false || $end === false) { return false; }
    if ($start > $end) {
        $temp = $start; 
        $start = $end;
        $end = $temp;
    }
    if ( $returnkeys === true) {
        $start = $start + strlen($key1);
        $length = $end - $start;
    } else {
        $length = ($end + strlen($key2)) - $start;  
    }
    return substr_replace($source, '', $start, $length);
}
?>

0

ด้วยข้อผิดพลาดบางอย่างที่จับ โดยเฉพาะฟังก์ชั่นส่วนใหญ่ที่นำเสนอต้องใช้ $ end ที่มีอยู่เมื่อในความเป็นจริงในกรณีของฉันฉันต้องการให้เป็นทางเลือก ใช้นี่คือ $ end เป็นตัวเลือกและประเมินเป็น FALSE หากไม่มีการเริ่มต้น $ เลย:

function get_string_between( $string, $start, $end ){
    $string = " " . $string;
    $start_ini = strpos( $string, $start );
    $end = strpos( $string, $end, $start+1 );
    if ($start && $end) {
        return substr( $string, $start_ini + strlen($start), strlen( $string )-( $start_ini + $end ) );
    } elseif ( $start && !$end ) {
        return substr( $string, $start_ini + strlen($start) );
    } else {
        return FALSE;
    }

}

0

คำตอบ @Alejandro Iglesias รุ่น UTF-8 จะทำงานกับอักขระที่ไม่ใช่ละติน:

function get_string_between($string, $start, $end){
    $string = ' ' . $string;
    $ini = mb_strpos($string, $start, 0, 'UTF-8');
    if ($ini == 0) return '';
    $ini += mb_strlen($start, 'UTF-8');
    $len = mb_strpos($string, $end, $ini, 'UTF-8') - $ini;
    return mb_substr($string, $ini, $len, 'UTF-8');
}

$fullstring = 'this is my [tag]dog[/tag]';
$parsed = get_string_between($fullstring, '[tag]', '[/tag]');

echo $parsed; // (result = dog)

0

มีทางออกที่ดีที่สุดสำหรับสิ่งนี้จากtonyspiro

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

0

สามารถทำได้อย่างง่ายดายโดยใช้ฟังก์ชั่นขนาดเล็กนี้:

function getString($string, $from, $to) {
    $str = explode($from, $string);
    $str = explode($to, $str[1]);
    return $s[0];
}
$myString = "<html>Some code</html>";
print getString($myString, '<html>', '</html>');

// Prints: Some code

-1

ฉันใช้มันมาหลายปีแล้วและใช้งานได้ดี อาจจะทำให้มีประสิทธิภาพมากขึ้น แต่

grabstring ("สตริงการทดสอบ", "," ", 0) ส่งคืนสตริงการทดสอบ
grabstring (" สตริงการทดสอบ "," ทดสอบ "," ", 0) ส่งคืนสตริง
grabstring (" สตริงการทดสอบ "," s "," ", 5) ส่งคืนสตริง

function grabstring($strSource,$strPre,$strPost,$StartAt) {
if(@strpos($strSource,$strPre)===FALSE && $strPre!=""){
    return("");
}
@$Startpoint=strpos($strSource,$strPre,$StartAt)+strlen($strPre);
if($strPost == "") {
    $EndPoint = strlen($strSource);
} else {
    if(strpos($strSource,$strPost,$Startpoint)===FALSE){
        $EndPoint= strlen($strSource);
    } else {
        $EndPoint = strpos($strSource,$strPost,$Startpoint);
    }
}
if($strPre == "") {
    $Startpoint = 0;
}
if($EndPoint - $Startpoint < 1) {
    return "";
} else {
        return substr($strSource, $Startpoint, $EndPoint - $Startpoint);
}

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.