2013-03-25 9 views
19

Pobiegłem następujący skrypt korzystając php.exe:awarii PHP na preg_replace

preg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string); 

lub jego odpowiednika:

preg_replace('#(?:^[^\pL]*|[^\pL]*$)#u','',$string); 

If $string="S" lub $string=" ذذ " to działa, jeśli string='ذ' to daje że jest błędne, i jesli string='ذذ' PHP zawiesza sie.

Ale działa w wersjach 4.4.0 - 4.4.9, 5.0.5 - 5.1.6.

Co jest nie tak?

Zobacz: http://3v4l.org/T3rpV


<?php 
$string='دد'; 
echo preg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string); 

Wyjście 5.4.0 - 5.5.0alpha6

Process exited with code 139. 

Wyjście 5.2.0 - 5.3.22, 5.5.0beta1

 

Wyjście 4.4.0 - 4.4.9, 5.0.5 - 5.1.6

دد 

wyjście dla 4.3.11, 5.0.0 - 5.0.4

Warning: preg_replace(): Compilation failed: PCRE does not support \L, \l, \N, \P, \p, \U, \u, or \X at offset 7 in /in/T3rpV on line 3 

Output do 4.3.0 - 4.3.10

Warning: Compilation failed: PCRE does not support \L, \l, \N, \P, \p, \U, \u, or \X at offset 7 in /in/T3rpV on line 3 
+2

to wywala tutaj też. PHP 5.4.7. –

+0

Mogę potwierdzić, że zawiesza się również w najnowszej wersji beta ** PHP 5.5.0beta2 ** (wydanej 28 marca)! – ComFreek

+0

@ComFreek Czy moja odpowiedź również powoduje awarię? –

Odpowiedz

0

Wreszcie błąd został rozwiązany:

Output for 4.4.0 - 4.4.9, 5.0.5 - 5.1.6, 5.5.27 - 5.5.33, 5.6.11 - 7.0.4, hhvm-3.6.1 - 3.12.0 
    دد 
5

można użyć alternatywa mb_ereg_replace function():

mb_internal_encoding("UTF-8"); 
mb_regex_encoding("UTF-8"); 
echo mb_ereg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string); 
+0

nie, nie możesz jej [zobacz] (http://www.php.net/manual/en/function.mb-ereg-replace.php) –

+0

Twój regex działa zupełnie inaczej i nie jest równoważny z moim. Spróbuj: '$ string = '. D.'' – PHPst

+0

mój regex !!! Nie widzę tego! –

3

może to pomoże:

właściwości te są przeważnie dostępne tylko wtedy, gdy PCRE jest skompilowany z "--enable-unicode-properties"

http://docs.php.net/manual/en/regexp.reference.unicode.php#96479

+1

Jeśli te właściwości nie są dostępne, PHP będzie wysyłać ostrzeżenia zamiast awarii. –

+0

Z własnego doświadczenia, miałem ciężkie chwile, gdy \ b (jakikolwiek znak na granicy wyrazów) nie działał po cichu z symbolami cyrylicy, po prostu je ignorował, z drugiej strony, pracując zgodnie z przeznaczeniem z łacińskim. Musiałem używać potworów takich jak: '$ boundL = '(^ | [- \ s \.><,:; \! \?] +)';' '$ boundR = '($ | [- \ s \.><,:; \! \?] +) ";' –

0

Użyj preg_quote i musisz poprawnie uciec przed specjalnym znakiem, zanim użyjesz go ze swoim wyrażeniem regularnym. Na przykład:

<?php 
$string = preg_quote("\دد"); 
echo preg_replace('#(?:^[^\pL]*)|(?:[^\pL]*$)#u','',$string); 

Zobacz go w akcji: http://3v4l.org/LeBXg

Więcej o preg_quote.

Cheers,

Ardy

+0

'preg_quote' Cytuj wyrażenia regularne znaków i nie jest konieczne dla normalnych znaków. Bur nawet 'echo preg_replace ('# (?:^[^ \ PL] * | [^ \ pL] * $) # u', '', preg_quote ('ذذ'));' crashs. 'preg_quote (" \ دد ");' to '\\ ss', który jest innym ciągiem. – PHPst

+0

Być może źle zrozumiałeś cel 'preg_quote()', ma on na celu unikanie znaków specjalnych do użycia * wewnątrz * wyrażeń regularnych :) –

+0

@PHPst: good catch, my bad. –

1

Od patrząc na samej wypowiedzi, są dwie rzeczy, które mogłyby być lepsze:

  1. W * mnożniki nie są bardzo przydatne; dlaczego chciałbyś zamienić potencjalnie pusty mecz na pusty ciąg znaków? W rzeczywistości uruchomienie tego w moim systemie daje NULL z operacji preg_replace().

  2. Grupy pamięci można łączyć.

Jest to kod po zastosowaniu zarówno ulepszenia:

$string = 'ﺫﺫ'; 
var_dump(preg_replace('#(?:^[^\pL]+|[^\pL]+$)#u', '', $string)); 
// string(4) "ﺫﺫ" 

3v4l results

Jeśli szukasz po prostu funkcji wielobajtowego trymowania (obsługiwane począwszy od 4.3.0):

$string=' دد'; 
var_dump(preg_replace('#(?:^\s+|\s+$)#u', '', $string)); 

3v4l results

+0

"W rzeczywistości uruchomienie tego w moim systemie daje NULL" Wow! Właściwie znalazłeś inny błąd: http://3v4l.org/H1Ihk – PHPst

+0

@PHPst Wygląda to jak :) Czy kod w mojej odpowiedzi jest pomocny? –

+0

@Jack Nie ulega awarii, ale wypisuje 'string (6)" ذذ "' zamiast oczekiwanego rezultatu. – ComFreek