2013-10-11 12 views
20

ich preg_replace in PHP bin mit zu finden und bestimmte Wörter in einem String zu ersetzen, wie folgt aus:PHP preg_replace: Groß- und Kleinschreibung Übereinstimmung mit Groß- und Kleinschreibung Ersatz

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

die das Ergebnis ‚Birne Birne‘ gibt.

Was ich gerne tun könnte, ist ein Wort in einer Groß-und Kleinschreibung nicht übereinstimmen, aber respektieren, es ist der Fall, wenn es ersetzt wird - mit dem Ergebnis "Birne Birne".

Die folgenden Werke, aber es scheint ein wenig lang mir umständliche:

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

Gibt es einen besseren Weg, dies zu tun?

Update: Neben einer ausgezeichneten Abfrage unten, für die Zwecke dieser Aufgabe möchte ich nur 'Titel Case' respektieren - also, ob der erste Buchstabe eines Wortes ein Kapital ist oder nicht.

+0

Die einzige Sache, die unklar bleibt: Was ist, wenn Ihr Ersatz- und Originalwort unterschiedliche Länge und Originalwort hat Großbuchstabe auf höherer Position? I.e. '' applie'' und '' pean'' was dann? –

+0

Ausgezeichneter Punkt. Für die Zwecke dieser speziellen Aufgabe möchte ich nur den "Titelfall" respektieren (also, ob der erste Buchstabe ein Großbuchstabe ist oder nicht). Vielen Dank für weitere Klarheit. – colin

Antwort

7

Ich habe diese Implementierung für gemeinsamen Fall im Sinne:

$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" 

-en sind komplizierter, natürlich, aber passen ursprüngliche Anforderung für jede Position. Wenn Sie nur die ersten Buchstaben suchen, könnte dies ein viel des Guten (siehe @ Jon Antwort dann)

10

Sie können dies tun, mit preg_replace_callback, aber das ist noch lange umständliches:

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

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

Dieser Code sieht nur bei der Aktivierung des ersten Zeichens des Spiels zu bestimmen, was mit zu ersetzen; Sie könnten den Code anpassen, um stattdessen etwas mehr zu tun.

+0

Ich habe versucht, Ihren Code, aber ich erhalte Catchable fatalen Fehler: Objekt der Klasse Closure konnte nicht in Zeichenfolge umgewandelt werden ... – c3cris

+0

@ c3cris Ich hatte fälschlicherweise nur 'preg_replace' anstelle von' preg_replace_callback' oben im Schnipsel geschrieben, obwohl die Erwähnung in der ersten Zeile war richtig. Fest. – Jon

+0

Dies ist eine weitaus elegantere Lösung. Viel kürzer und einfacher auf einen Blick zu verstehen. +1 – JustCarty

3

Dies ist die Lösung, die ich verwendet:

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

In den besten Worte, die ich kann ich Versuchen Sie zu erklären, warum das funktioniert: Wenn Sie Ihren Suchbegriff mit () einpacken, möchte ich später auf diesen Wert zugreifen. Da es das erste Element in Pars in der RegEx ist, ist es mit $1 zugänglich, wie Sie in der Substitution Parameter sehen können

+0

Und schauen Sie sich den Unterschied zwischen dieser und der erwarteten Antwort. Eine große Erinnerung an alle Ingenieure, "es einfach zu halten". – Meiji

Verwandte Themen