PHP एक स्ट्रिंग में एक स्ट्रिंग की अंतिम घटना को बदलें?


145

किसी को भी एक स्ट्रिंग में एक और स्ट्रिंग के साथ एक स्ट्रिंग की अंतिम घटना को बदलने के लिए बहुत तेज़ तरीके से पता है?


आपको s($str)->replaceLast($search, $replace)मदद मिल सकती है , जैसा कि इस स्टैंडअलोन लाइब्रेरी में पाया गया है ।
caw

जवाबों:


228

आप इस फ़ंक्शन का उपयोग कर सकते हैं:

function str_lreplace($search, $replace, $subject)
{
    $pos = strrpos($subject, $search);

    if($pos !== false)
    {
        $subject = substr_replace($subject, $replace, $pos, strlen($search));
    }

    return $subject;
}

यह अभी भी कोई बात नहीं क्या सच लौट रहा था। इसे संशोधित करने पर विचार करें: यदि ($ पॉस) {$ विषय = root_replace ($ विषय, $ प्रतिस्थापित, $ pos, स्ट्रलेन ($ खोज)); $ विषय वापस; } और {झूठा वापस; }
Jazzy

4
@ जेसन यह TRUEकोई बात नहीं क्या वापस नहीं करता है । यह एक स्ट्रिंग देता है, चाहे जो भी हो। यदि कोई प्रतिस्थापन नहीं किया जा सकता है तो यह मूल रिटर्न देता है $subject, जैसे substr_replace और str_replaceकरते हैं।
मिशा

@Mischa इस मामले में एक ही बात नहीं है? मैं कुछ करने की कोशिश कर रहा था! Str_lreplace, लेकिन अगर यह झूठ नहीं लौटता है, तो इसे सही माना जाता है, है ना? किसी भी तरह से, इससे मुझे मदद मिली और मैंने इसकी सराहना की। धन्यवाद।
जैज़ी

1
यह कैसे काम कर सकता है? strpos — Find the position of the first occurrence of a substring in a string- संपादित करें: वाह। Php प्रतिभाओं ने वास्तव में एक समारोह बुलाया strposऔर strrpos? धन्यवाद ....
बैरीबोनस ४१

1
@Barry इस एक मामले में जहां पीएचपी दोष लायक नहीं है :-) नाम दशकों पुरानी पर नमूनों कर रहे हैं strstr, strrstrमानक सी पुस्तकालय की, जो एक ही कार्य हैं। (लेकिन उन्होंने किया है नाम बदलने के लिए?)
एलेक्सिस

30

एक और 1-लाइनर लेकिन बिना प्रीग:

$subject = 'bourbon, scotch, beer';
$search = ',';
$replace = ', and';

echo strrev(implode(strrev($replace), explode(strrev($search), strrev($subject), 2))); //output: bourbon, scotch, and beer

3
एफडब्ल्यूआईडब्ल्यू, स्वीकृत समाधान इस समाधान की तुलना में लगभग 35% तेज है।
जस्टकार्टी

27
$string = 'this is my world, not my world';
$find = 'world';
$replace = 'farm';
$result = preg_replace(strrev("/$find/"),strrev($replace),strrev($string),1);
echo strrev($result); //output: this is my world, not my farm

मेरी राय में सबसे अच्छा समाधान और अभी भी समझने के लिए उत्सुक।
ब्लैकबैम

क्यों यह उलटे हुए सभी तारों के साथ काम करता है? क्या रेगुलर-एक्सप्रेशन का उपयोग करते समय कुछ (मुझे लगता है) विशिष्ट प्रदर्शन लाभ है?
कामाफेदर

नहीं, यह वास्तव में प्रदर्शन को कम करता है, लेकिन यह इसलिए है क्योंकि आप अंतिम घटना चाहते हैं ताकि आप खोज को केवल एक तक सीमित कर सकें और सब कुछ उल्टा कर सकें यदि आप चाहते थे कि आपको पहले कुछ भी उलटना न पड़े
तोफंडेल

15

निम्नलिखित बल्कि कॉम्पैक्ट समाधान ब्याज की सबस्ट्रिंग की अंतिम घटना से मेल करने के लिए PCRE पॉजिटिव लुकहैड एश्योरेंस का उपयोग करता है , अर्थात, सबस्ट्रिंग की एक घटना जो उसी प्रतिस्थापन के किसी भी अन्य घटना के बाद नहीं होती है। इस प्रकार उदाहरण के last 'fox'साथ बदल देता है 'dog'

$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!';
echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);

उत्पादन: 

The quick brown fox, fox, fox jumps over the lazy dog!!!

5
विचार अच्छा है, लेकिन कोड नहीं है। यह होना चाहिए:$string = 'The quick brown fox, fox, fox jumps over the lazy fox!!!'; echo preg_replace('/(fox(?!.*fox))/', 'dog', $string);
Roemer

वास्तव में, मैंने जो कोड पोस्ट किया है, वह "लोमड़ी" के सभी उदाहरणों को बदलता है, पिछले एक "कुत्ते" को छोड़कर, लेकिन हम जो चाहते हैं वह बिल्कुल विपरीत है। उस बदले की ओर इशारा करने के लिए धन्यवाद? = साथ! समस्या को ठीक करता है।
जॉन सोंडरसन

11

आप ऐसा कर सकते हैं:

$str = 'Hello world';
$str = rtrim($str, 'world') . 'John';

परिणाम 'हैलो जॉन' है;

सादर


4
यह तब तक काम करता है जब तक कोई दोहराए जाने वाला वर्ण नहीं है। मेरी स्थिति में मैं संग्रह की तारीख से पृष्ठ संख्या को हटा रहा हूं, इसलिए मेरे पास "2015-12 / 2" है और यह "2015-1" बनने के अंत में सभी / और सभी 2 को बंद कर देता है।
माइक

यह केवल तभी काम करेगा जब खोज की गई अंतिम घटना अंतिम शब्द है और इसके बाद कोई अतिरिक्त वर्ण नहीं है।
विस्मयकारी

यह काम नहीं करता क्योंकि rtrimआप जिस तरह से सोच रहे हैं वैसा व्यवहार नहीं करता है। यह किसी भी क्रम में खोज स्ट्रिंग में मौजूद किसी भी वर्ण (और हमेशा प्रतिस्थापन को जोड़ देगा) से पट्टी करेगा, उदाहरण के लिए "हैलो शब्द" -> "हैलो जॉन", "हैलो भगवान" -> "हैलो जॉन", "हैलो मोटर "->" हैलो मोटजन "," हैलो दुनियादार "->" हैलो दुनियाजोन "।
जेक

5

यह भी काम करेगा:

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '(.*?)~', '$1' . $replace . '$2', $subject, 1);
}

अद्यतन थोड़ा अधिक संक्षिप्त संस्करण ( http://ideone.com/B8i4o ):

function str_lreplace($search, $replace, $subject)
{
    return preg_replace('~(.*)' . preg_quote($search, '~') . '~', '$1' . $replace, $subject, 1);
}

क्या मैं गलत कर रहा हूँ? यदि ऐसा है तो बस मुझे अनदेखा करें :) ||| इको str_lreplace ("x", "y", "यह x या वह x"); => आउटपुट: "y" देखें: ideone.com/UXuTo
edorian

@ एडोरियन: उफ़! क्षमा करें, मैंने पोस्ट किया कि जल्दी में, सही संस्करण यहाँ है: ideone.com/vR073
एलिक्स एक्सल

5

कोड की सिर्फ एक पंक्ति (देर से जवाब लेकिन यह जोड़ने लायक है):

$string = 'The quick brown fox jumps over the lazy dog';
$find_me = 'dog';

preg_replace('/'. $find_me .'$/', '', $string);

अंत $ स्ट्रिंग के अंत को इंगित करता है।


5

यह एक प्राचीन प्रश्न है, लेकिन हर कोई सरलतम रीजैक्स-आधारित समाधान की अनदेखी क्यों कर रहा है? सामान्य regexp quantifiers लालची हैं, लोग! यदि आप किसी पैटर्न के अंतिम उदाहरण को ढूंढना चाहते हैं, तो बस उसके .*सामने चिपके रहें । ऐसे:

$text = "The quick brown fox, fox, fox, fox, jumps over etc.";
$fixed = preg_replace("((.*)fox)", "$1DUCK", $text);
print($fixed);

यह "लोमड़ी" के अंतिम उदाहरण को "DUCK" में बदल देगा, जैसे कि यह माना जाता है, और प्रिंट करें:

The quick brown fox, fox, fox, DUCK, jumps over etc.

1
धन्यवाद! इसे पूरा करने के लिए मेरी अभिव्यक्ति के चारों ओर लपेटने का सही कार्य। मेरे मामले में मैं अंतिम कॉमा को "और" के साथ बदल रहा हूं। खुशी है कि मैंने इस उत्तर सूची में थोड़ा नीचे स्क्रॉल किया।
rlhane

3
$string = "picture_0007_value";
$findChar =strrpos($string,"_");
if($findChar !== FALSE) {
  $string[$findChar]=".";
}

echo $string;

कोड में गलतियों के अलावा, फ़ारुक उनल के पास सबसे अच्छा अन्वेषक है। एक फ़ंक्शन ट्रिक करता है।


आपको जांचने की ज़रूरत है, अगर $ findChar गलत नहीं है (उसी तरह जैसे कि स्वीकृत उत्तर में)। यदि स्ट्रिंग में खोजा हुआ स्ट्रिंग नहीं है, तो आपको सूचना मिलती है और पहले वर्ण को बदल दिया जाएगा।
झबरा

यह बहुत अच्छा है, लेकिन जैसा कि यह खड़ा है यह केवल 1 चरित्र के साथ 1 चरित्र को बदल सकता है।
पीट

3

अंतिम मैच खोजने के लिए आप स्ट्रैप () का उपयोग कर सकते हैं।

$string = "picture_0007_value";
$findChar =strrpos($string,"_");

$string[$findChar]=".";

echo $string;

आउटपुट: picture_0007.value


2

स्वीकृत उत्तर के लिए आशुलिपि

function str_lreplace($search, $replace, $subject){ 
    return is_numeric($pos=strrpos($subject,$search))?
    substr_replace($subject,$replace,$pos,strlen($search)):$subject;
}


0

स्ट्रिंग के अंत से मेल खाने के लिए एक reg अभिव्यक्ति पर "$" का उपयोग करें

$string = 'The quick brown fox jumps over the lazy fox';
echo preg_replace('/fox$/', 'dog', $string);

//output
'The quick brown fox jumps over the lazy dog'

4
यह तभी काम करता है जब अंतिम घटना स्ट्रिंग ideone.com/nbNSNq
cawecoy

1
यदि अंतिम 'लोमड़ी' के बाद कोई अन्य वर्ण दिखाई देता है तो यह काम नहीं करेगा।
जॉन सोंडरसन

0

रुचि के लिए: मैंने एक फ़ंक्शन लिखा है जो preg_match का उपयोग करता है ताकि आप regex का उपयोग करके दाहिने हाथ की ओर से बदल सकें।

function preg_rreplace($search, $replace, $subject) {
    preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
    $lastMatch = end($matches);

    if ($lastMatch && false !== $pos = strrpos($subject, $lastMatchedStr = $lastMatch[0])) {
        $subject = substr_replace($subject, $replace, $pos, strlen($lastMatchedStr));
    }

    return $subject;
}

या दोनों विकल्पों के शॉर्टहैंड संयोजन / कार्यान्वयन के रूप में:

function str_rreplace($search, $replace, $subject) {
    return (false !== $pos = strrpos($subject, $search)) ?
        substr_replace($subject, $replace, $pos, strlen($search)) : $subject;
}
function preg_rreplace($search, $replace, $subject) {
    preg_match_all($search, $subject, $matches, PREG_SET_ORDER);
    return ($lastMatch = end($matches)) ? str_rreplace($lastMatch[0], $replace, $subject) : $subject;
}

https://stackoverflow.com/a/3835653/3017716 और https://stackoverflow.com/a/23343396/3017716 पर आधारित

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.