2013-03-16 14 views
67

Jestem okropny z wyrażeń regularnych. Próbuję zastąpić to:Zastąp zmiennik preg_replace() e preg_replace_callback

public static function camelize($word) { 
    return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word); 
} 

z preg_replace_callback z anonimowej funkcji. Nie rozumiem, co robi \\ 2. Lub o to chodzi dokładnie jak działa preg_replace_callback.

Jaki byłby prawidłowy kod do osiągnięcia tego?

+1

gdzie ** e ** modyfikator [przestarzałe] (http://php.net/manual/en/reference.pcre.pattern.modifiers.php) w ​​PHP 5.5.0 – HamZa

+8

@HamZaDzCyberDeV znam . Jest to jeden z powodów, dla których chcę go zastąpić preg_replace_callback – Casey

+2

Istnieje strona podręcznika dla ['preg_replace_callback'] (http://php.net/preg_replace_callback). A '\\ 2' stanie się' $ matches [2] 'w tym wywołaniu zwrotnym. Albo w której części jesteś szczególnie zdezorientowany? – mario

Odpowiedz

59

W wyrażeniu regularnym można "przechwycić" części dopasowanego ciągu za pomocą (brackets); w takim przypadku przechwytujesz części dopasowania. Są one ponumerowane od 1, więc masz referencje zwrotne 1 i 2. Dopasowanie 0 to cały dopasowany ciąg.

/e modyfikator pobiera ciąg zastępczy, a substytuty BACKSLASH następuje numer (np \1) z odpowiednim odniesieniem wstecznego - ale dlatego, że jesteś w środku łańcucha, trzeba uciec backslash, więc masz '\\1' . Następnie (skutecznie) działa eval, aby uruchomić łańcuch wynikowy tak, jakby był to kod PHP (i dlatego jest przestarzały, ponieważ jest łatwy w użyciu w niezabezpieczony sposób, eval).

Zamiast tego funkcja preg_replace_callback przyjmuje funkcję zwrotną i przekazuje jej tablicę zawierającą dopasowane referencje zwrotne. Więc jeśli napisałbyś '\\1', zamiast tego uzyskasz dostęp do elementu 1 tego parametru - np. jeśli masz anonimową funkcję formularza function($matches) { ... }, pierwsza referencja zwrotna to $matches[1] wewnątrz tej funkcji.

Więc /e argument

'do_stuff(\\1) . "and" . do_stuff(\\2)' 

może stać się zwrotna od

function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); } 

lub w przypadku

'strtoupper("\\2")' 

może stać

function($m) { return strtoupper($m[2]); } 

Zauważ, że $m i $matches nie są magicznymi nazwami, to tylko nazwa parametru, którą podałem podczas deklarowania moich funkcji zwrotnych. Ponadto nie musisz przekazywać anonimowej funkcji, może to być nazwa funkcji w postaci ciągu lub coś w rodzaju postaci array($object, $method), as with any callback in PHP, np.

function stuffy_callback($things) { 
    return do_stuff($things[1]) . "and" . do_stuff($things[2]); 
} 
$foo = preg_replace_callback('/([a-z]+) and ([a-z]+)/', 'stuffy_callback', 'fish and chips'); 

Tak jak w przypadku każdej funkcji, domyślnie nie można uzyskać dostępu do zmiennych spoza twojego wywołania zwrotnego (z otaczającego zakresu). Podczas korzystania z funkcji anonimowej można użyć słowa kluczowego use w celu zaimportowania zmiennych potrzebnych do uzyskania dostępu, as discussed in the PHP manual. na przykładjeśli stary argumentem było

'do_stuff(\\1, $foo)' 

następnie nowy zwrotna może wyglądać

function($m) use ($foo) { return do_stuff($m[1], $foo); } 

pułapek

  • Zastosowanie preg_replace_callback jest zamiast/e modyfikator na regex, więc trzeba usunąć tę flagę z argumentu "pattern". Tak więc wzór taki jak /blah(.*)blah/mei stanie się /blah(.*)blah/mi.
  • Modyfikator /e użył wariantu addslashes() wewnętrznie na argumentach, więc niektóre zamienniki użyły stripslashes(), aby go usunąć; w większości przypadków prawdopodobnie chcesz usunąć połączenie z numerem stripslashes z nowego połączenia zwrotnego.
Powiązane problemy