ลบส่วนของสตริงหลังอักขระบางตัว


144

ฉันแค่สงสัยว่าฉันจะลบทุกอย่างหลังจากสตริงย่อยบางอย่างใน PHP

อดีต:

Posted On April 6th By Some Dude

ฉันต้องการที่จะมีมันเพื่อที่จะลบข้อความทั้งหมดรวมถึงและหลังจากที่สตริงย่อย "โดย"

ขอบคุณ


1
เกิดอะไรขึ้นถ้าสตริงย่อยเกิดขึ้นสองครั้ง (หรือมากกว่า)
Bart Kiers

18
เช่นเดียวกับโน้ตถ้าคุณกำลังทำเช่นนี้เพื่อให้คุณสามารถใช้เนื้อหาของคนอื่นและนำเสนอในเว็บไซต์ของคุณเองทำไม่ได้
ceejayoz

ฉันเห็นด้วยกับ ceejayoz สิ่งนี้ฟังดูคล้ายกับว่าคุณกำลังพยายามใช้เนื้อหาที่คุณไม่มีสิทธิ์เข้าถึงจริงๆและคุณพยายามลบการอ้างอิงใด ๆ ไปยังผู้แต่งดั้งเดิม ไม่ว่าจะมีความสุขมาก ...
selfawaresoup

2
stackoverflow.com/a/9315908/1518921 :) ทางเลือกที่ยอดเยี่ยมสำหรับการแก้ปัญหา
Guilherme Nascimento

1
เป็นเรื่องปกติที่จะต้องทำสิ่งนี้ด้วยเหตุผลที่ถูกต้องเมื่อทำงานกับเนื้อหาที่สร้างขึ้นโดย CMS เหตุผลที่คุณไม่ต้องการยุ่งกับรหัสจริงที่สร้างตัวอย่างเช่นนี้เพราะคุณจะทำลายการปรับปรุงของคุณ ดังนั้นคุณปล่อยให้มันทำสิ่งนั้นจากนั้นคุณทำสิ่งที่คุณ
Nosajimiki

คำตอบ:


292
$variable = substr($variable, 0, strpos($variable, "By"));

ในภาษาอังกฤษธรรมดา: ให้ฉันเป็นส่วนหนึ่งของสตริงเริ่มต้นที่จุดเริ่มต้นและสิ้นสุดที่ตำแหน่งที่คุณพบผู้กระทำความผิดครั้งแรก


11
สิ่งที่เกี่ยวกับ "ทำเฉพาะถ้า" โดย "มีอยู่?
Alisso

3
คุณถูก. strpos จะส่งคืน FALSE หากไม่พบ "By" substr จะส่งคืนสตริงว่างถ้าความยาวที่กำหนดเป็นเท็จ ในทางปฏิบัติมันอาจจะมีประโยชน์ในการตรวจสอบว่า "โดย" มีอยู่แล้วทำเช่นนี้ถ้ามัน (หรือเพียงแค่ปล่อยสตริงเพียงอย่างเดียว)
Austin Fitzpatrick

13
ใช้งานได้: strpos ($ variable, "By")? substr ($ variable, 0, strpos ($ variable, "By")): $ variable;
โนอาห์แกรี่

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

1
ทำงานได้สมบูรณ์แบบสำหรับฉัน @ Goahnary!
ปฏิเสธ

106

หากคุณใช้ PHP 5.3 ขึ้นไปดูที่ธง before_needle ของstrstr ()

$s = 'Posted On April 6th By Some Dude';
echo strstr($s, 'By', true);

4
ขอบคุณนี่คือคำตอบที่ถูกต้องจริงในปัจจุบัน !
Matmarbon

59
โปรดทราบว่ามันจะกลับมาFALSEถ้าส่วนของสตริงไม่พบ วิธีแก้ปัญหาอาจเป็น:echo strstr($s, 'By', true) ?: $s;
kenorb

6
^^^ คำตอบของ kenorb ควรเป็นคำตอบที่ได้รับการยอมรับในวันนี้ อีกทางเลือกหนึ่งจะเป็นexplode(' By', $s)[0]IMHO ของ squarecandy
Zack Morris

ที่จริงแล้วการตรวจสอบการมีอยู่ของ kenorb นั้นเป็นวิธีการทำแม้ว่าจะไม่จำเป็นต้องทดสอบสตริง
BarryMode

ที่นี่เพื่อบอกว่าวิธีการของ @ kenorb คือหัวนม
Quinn Comendant

32

วิธีใช้explode:

$input = 'Posted On April 6th By Some Dude';
$result = explode(' By',$input);
return $result[0];

ข้อดี:


@bkac - มีอะไรผิดปกติกับแฟชั่นแบบเก่าตราบใดที่มันใช้งานได้และไม่คิดค่าเสื่อมราคา?
squarecandy

3
สิ่งนี้จะกำจัดการตรวจสอบเพิ่มเติมสำหรับการมีอยู่ของสตริงตัวคั่นที่ต้องการโดยคำตอบที่ยอมรับ
David Cullen

17

คุณสามารถทำได้:

$posted = preg_replace('/ By.*/', '', $posted);
echo $posted;

4
+1 เป็นเพียงตัวเดียวที่ใช้งานได้หากไม่มีอักขระควบคุม (ไม่เหมือนกับอักขระอื่นที่ส่งคืนสตริงว่างถ้าไม่มีอักขระควบคุมอยู่ในสตริงต้นฉบับ)
Tom Auger

9

วิธีหนึ่งจะเป็น:

$str = 'Posted On April 6th By Some Dude';
echo strtok($str, 'By'); // Posted On April 6th

นี่เป็นคำตอบที่ดีที่สุดที่ใช้งานได้แม้ว่า By ไม่ได้อยู่ในสตริงคำตอบของ substr นั้นผิดเพราะมีอยู่โดย doest'nt มันล้มเหลว
neoteknic

สิ่งนี้ไม่ถูกต้อง: ฟังก์ชันจะไม่แยกตามByแต่ด้วยอักขระใด ๆ ในพารามิเตอร์ที่ 2 ความหมายก็จะแยกโดยทั้งหรือB ในทางเทคนิคแล้วมันไม่ได้รับทุกอย่างก่อนy By
msb

ระวัง: strtok จะส่งคืนส่วนของสตริงหลังตัวละครหากเป็นตัวอักษรตัวแรกในสตริงเช่นstrtok('a:b', ':')จะกลับมาaแต่strtok(':b', ':')จะกลับมาbไม่ใช่สตริงที่ว่างเปล่าตามที่คุณคาดหวัง
Quinn Comendant

6

ลองสิ่งนี้

function strip_after_string($str,$char)
    {
        $pos=strpos($str,$char);    
        if ($pos!==false) 
        {
            //$char was found, so return everything up to it.
            return substr($str,0,$pos);
        } 
        else 
        {
            //this will return the original string if $char is not found.  if you wish to return a blank string when not found, just change $str to ''
            return $str; 
        }
    }

การใช้งาน:

<?php
    //returns Apples
    $clean_string= strip_after_string ("Apples, Oranges, Banannas",",");
?>

คุณจะดีกว่าการตั้งชื่อฟังก์ชั่น strip_after_string แทน SAS และมีรหัสฐานที่เต็มไปด้วยการเริ่มต้นที่คลุมเครือ นี่เป็นคำตอบที่ฉันชอบมากที่สุดที่อ่านได้สำหรับคำถามนี้
Anther

5

คำตอบของ Austin เหมาะสำหรับกรณีตัวอย่างของคุณ

โดยทั่วไปแล้วคุณควรศึกษาฟังก์ชั่นการแสดงออกปกติเมื่อสตริงย่อยที่คุณแยกอาจแตกต่างกันระหว่างสตริง:

$ variable = preg_replace ('/ By. * /', '', $ variable);

+1 นี่ถูกต้อง หากคุณต้องการแยกใน "ผู้แต่ง:" หรือ "เขียนโดย:" หรือ "ใช้โดยได้รับความยินยอมจาก:" อาจเป็นวิธีที่ง่ายที่สุดในการสร้างนิพจน์ทั่วไป เมื่อฉันไม่ทำตรรกะ regex ใด ๆ ฉันมักจะหลีกเลี่ยงพวกเขาเนื่องจากพวกเขาดูเหมือนจะเพิ่มระดับความซับซ้อนให้กับโค้ด (อย่างน้อยสำหรับฉัน) ในทันที
Austin Fitzpatrick

4

คุณสามารถใช้listและexplodeฟังก์ชั่น:

list($result) = explode("By", "Posted On April 6th By Some Dude", 2);
// $result is "Posted On April 6th "

นี่คือสิ่งที่ถูกต้องที่สุด ฉันหวังว่าฉันจะโหวตสองครั้งนี้ได้
John Max




2

ด้านล่างเป็นวิธีที่มีประสิทธิภาพมากที่สุด (ตามเวลาทำงาน) เพื่อตัดทุกอย่างหลังจากแรกโดยในสตริง หากByไม่มีอยู่สตริงทั้งหมดจะถูกส่งคืน ผลลัพธ์จะเป็น $ sResult

$sInputString = "Posted On April 6th By Some Dude";
$sControl = "By";

//Get Position Of 'By'
$iPosition = strpos($sInputString, " ".$sControl);
if ($iPosition !== false)
  //Cut Off If String Exists
  $sResult = substr($sInputString, 0, $iPosition);
else
  //Deal With String Not Found
  $sResult = $sInputString;

//$sResult = "Posted On April 6th"

หากคุณไม่ต้องการให้ตรงตามตัวพิมพ์ใหญ่ - เล็กให้ใช้striposแทน strpos หากคุณคิดว่าโดยอาจจะมีอยู่มากกว่าหนึ่งครั้งและต้องการที่จะตัดทุกอย่างหลังจากที่เกิดขึ้นที่ผ่านมาการใช้strrpos

ด้านล่างเป็นวิธีที่มีประสิทธิภาพน้อยลง แต่ใช้พื้นที่โค้ดน้อยลง วิธีนี้มีความยืดหยุ่นมากกว่าและช่วยให้คุณสามารถแสดงออกได้ตามปกติ

$sInputString = "Posted On April 6th By Some Dude";
$pControl = "By";

$sResult = preg_replace("' ".$pControl.".*'s", '', $sInputString);

//$sResult = "Posted On April 6th"

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

$sInputString = "Posted On April 6th By Some Dude";
$pControl = "[0-9]{1,2}[a-z]{2}"; //1 or 2 numbers followed by 2 lowercase letters.

$sResult = preg_replace("' ".$pControl.".*'s", '', $sInputString);

//$sResult = "Posted On April"

สำหรับตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ให้เพิ่มตัวดัดแปลง i ดังนี้:

$sResult = preg_replace("' ".$pControl.".*'si", '', $sInputString);

หากต้องการให้ทุกอย่างผ่านไปได้โดยเมื่อคุณคิดว่าอาจมีมากกว่าหนึ่งให้เพิ่มพิเศษ * ที่จุดเริ่มต้นเช่นนี้:

$sResult = preg_replace("'.* ".$pControl.".*'si", '', $sInputString);

แต่นี่ก็เป็นวิธีที่ทรงพลังจริงๆคุณสามารถใช้ preg_match เพื่อทำสิ่งที่คุณอาจพยายามทำ:

$sInputString = "Posted On April 6th By Some Dude";

$pPattern = "'Posted On (.*?) By (.*?)'s";
if (preg_match($pPattern, $sInputString, $aMatch)) {
  //Deal With Match
  //$aMatch[1] = "April 6th"
  //$aMatch[2] = "Some Dude"
} else {
  //No Match Found
}

การแสดงออกปกติอาจดูสับสนในตอนแรก แต่พวกเขาอาจมีพลังมากและเป็นเพื่อนที่ดีที่สุดของคุณเมื่อคุณเชี่ยวชาญ! โชคดี!


1

ทำไม...

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

ที่อยู่นี้ต่อไปนี้:

  • ผลกระทบด้านประสิทธิภาพของการใช้ REGEX กับ strrpos / strstr / strripos / stristr
  • การใช้ strripos / strrpos เมื่อไม่พบอักขระ / สตริงในสตริง
  • ลบออกจากด้านซ้ายหรือด้านขวาของสตริง (เกิดครั้งแรกหรือครั้งสุดท้าย)
  • ความไวของ CaSe
  • ต้องการความสามารถในการคืนกลับสตริงเดิมไม่เปลี่ยนแปลงถ้าค้นหาอักขระ / สตริงไม่พบ

การใช้งาน:

ส่งสตริงต้นฉบับค้นหาอักขระ / สตริง "R" / "L" เพื่อเริ่มต้นทางด้านขวาหรือด้านซ้ายจริง / เท็จสำหรับความไวของตัวพิมพ์เล็ก ตัวอย่างเช่นค้นหาตัวพิมพ์เล็กและใหญ่ที่ด้านขวาเป็นสตริง

echo TruncStringAfterString("Now Here Are Some Words Here Now","here","R",false);

การส่งออกจะเป็น "ตอนนี้มีบางคำ" การเปลี่ยน "R" เป็น "L" จะเป็นผลลัพธ์: "Now"

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

function TruncStringAfterString($origString,$truncChar,$startSide,$caseSensitive)
{
    if ($caseSensitive==true && strstr($origString,$truncChar)!==false)
    {
        // IF START RIGHT SIDE:
        if (strtoupper($startSide)=="R" || $startSide==false)
        {   // Found, strip off all chars from truncChar to end
            return substr($origString,0,strrpos($origString,$truncChar));
        }

        // IF START LEFT SIDE: 
        elseif (strtoupper($startSide)=="L" || $startSide="" || $startSide==true)
        {   // Found, strip off all chars from truncChar to end
            return strstr($origString,$truncChar,true);
        }           
    }
    elseif ($caseSensitive==false && stristr($origString,$truncChar)!==false)
    {           
        // IF START RIGHT SIDE: 
        if (strtoupper($startSide)=="R" || $startSide==false)
        {   // Found, strip off all chars from truncChar to end
            return substr($origString,0,strripos($origString,$truncChar));
        }

        // IF START LEFT SIDE: 
        elseif (strtoupper($startSide)=="L" || $startSide="" || $startSide==true)
        {   // Found, strip off all chars from truncChar to end
            return stristr($origString,$truncChar,true);
        }
    }       
    else
    {   // NOT found - return origString untouched
        return $origString;     // Nothing to do here
    }           

}

หากคุณลงคะแนนคำตอบในการทำงานของฉันมันจะได้รับการชื่นชมว่าคุณระบุว่าทำไม
Robert Mauro

0

ใช้ฟังก์ชั่นstrstr

<?php
$myString = "Posted On April 6th By Some Dude";
$result = strstr($myString, 'By', true);

echo $result ;

พารามิเตอร์ที่สามtrueบอกให้ฟังก์ชั่นส่งคืนทุกอย่างก่อนที่จะเกิดขึ้นครั้งแรกของพารามิเตอร์ที่สอง


1
strtok($str, 'By')ดูเรียบง่ายขึ้น
mu3

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