2013-10-11 5 views
20

मैं PHP में preg_replace उपयोग कर रहा हूँ खोजने के लिए और एक स्ट्रिंग में विशिष्ट शब्दों को बदलने के लिए, इस तरह के साथ मामले असंवेदनशील मैच:पीएचपी preg_replace: केस संवेदी प्रतिस्थापन

$subject = "Apple apple"; 
print preg_replace('/\bapple\b/i', 'pear', $subject); 

कौन सा परिणाम 'नाशपाती नाशपाती' देता है।

मैं जो करना चाहता हूं वह एक मामले में असंवेदनशील तरीके से एक शब्द से मेल खाता है, लेकिन इसे बदलने के मामले का सम्मान करें - परिणाम 'नाशपाती नाशपाती' देना।

निम्नलिखित काम करता है, लेकिन एक छोटे से लंबे समय से मेरे लिए चढ़ा हुआ लगता है:

$pattern = array('/Apple\b/', '/apple\b/'); 
$replacement = array('Pear', 'pear'); 
$subject = "Apple apple"; 
print preg_replace($pattern, $replacement, $subject); 

वहाँ यह करने के लिए एक बेहतर तरीका है?

अपडेट: इस कार्य के प्रयोजनों के लिए नीचे उठाए गए एक उत्कृष्ट प्रश्न के आगे मैं केवल 'शीर्षक केस' का सम्मान करना चाहता हूं - तो एक शब्द का पहला अक्षर पूंजी है या नहीं।

+0

एकमात्र चीज जो अस्पष्ट बनी हुई है: क्या होगा यदि आपके प्रतिस्थापन और मूल शब्द की अलग-अलग लंबाई और मूल शब्द हो उच्च पद पर पूंजी पत्र? अर्थात। तब 'सेब' और 'पियर' क्या? –

+0

उत्कृष्ट बिंदु। इस विशेष कार्य के प्रयोजनों के लिए, मैं केवल 'शीर्षक केस' का सम्मान करना चाहता हूं (इसलिए पहला पत्र पूंजी है या नहीं)। और स्पष्टता जोड़ने के लिए बहुत बहुत धन्यवाद। – colin

उत्तर

7

मैं आम मामले के लिए इस कार्यान्वयन मन में है। आप केवल पहला अक्षर लिए देख रहे हैं, यह एक overkill हो सकता है (देखें @ जॉन का जवाब तो)

10

आप preg_replace_callback के साथ ऐसा कर सकता है, लेकिन है कि और भी अधिक घना है:

$replacer = function($matches) { 
    return ctype_lower($matches[0][0]) ? 'pear' : 'Pear'; 
}; 

print preg_replace_callback('/\bapple\b/i', $replacer, $subject); 

इस कोड को सिर्फ मैच की पहली चरित्र क्या साथ बदलने के लिए निर्धारित करने के लिए का पूंजीकरण पर लग रहा है; आप इसके बजाय कुछ और शामिल करने के लिए कोड अनुकूलित कर सकते हैं।

$data = 'this is appLe and ApPle'; 
$search = 'apple'; 
$replace = 'pear'; 

$data = preg_replace_callback('/\b'.$search.'\b/i', function($matches) use ($replace) 
{ 
    $i=0; 
    return join('', array_map(function($char) use ($matches, &$i) 
    { 
     return ctype_lower($matches[0][$i++])?strtolower($char):strtoupper($char); 
    }, str_split($replace))); 
}, $data); 

//var_dump($data); //"this is peaR and PeAr" 

-यह के और अधिक जटिल, किसी भी स्थिति के लिए मूल अनुरोध जाहिर है, लेकिन फिट:

+0

मैंने आपके कोड की कोशिश की, लेकिन मुझे पकड़ने योग्य घातक त्रुटि मिलती है: क्लास क्लोजर का ऑब्जेक्ट स्ट्रिंग में परिवर्तित नहीं किया जा सका ... – c3cris

+0

@ c3cris मैंने गलती से उपरोक्त स्निपेट में 'preg_replace_callback' के बजाय' preg_replace' लिखा था, भले ही पहली पंक्ति में उल्लेख सही था। फिक्स्ड। – Jon

+0

यह एक बहुत ही सुरुचिपूर्ण समाधान है। एक नज़र में समझने के लिए बहुत छोटा और सरल। +1 – JustCarty

3

यह समाधान है कि मैं प्रयोग किया जाता है:

$result = preg_replace("/\b(foo)\b/i", "<strong>$1</strong>", $original); 

सबसे अच्छा शब्द है कि मैं मैं कर सकते हैं यह समझाएगा कि यह क्यों काम करता है: () के साथ अपना खोज शब्द लपेटना मतलब है कि मैं बाद में इस मान को एक्सेस करना चाहता हूं। चूंकि यह RegEx में पार्स में पहला आइटम है, यह $1 के साथ सुलभ है, जैसा कि आप प्रतिस्थापन पैरामीटर

+0

और उस और अपेक्षित उत्तर के बीच के अंतर को देखें। सभी इंजीनियरों को "इसे सरल रखना" के लिए एक महान अनुस्मारक। – Meiji

संबंधित मुद्दे