Internet Windows Android

PHP Text Encoding Determination - O prezentare generală a soluțiilor existente plus încă o bicicletă. Determinarea codificării textului PHP - O privire de ansamblu asupra soluțiilor existente Plus o altă codificare a paginii Windows Bike Php 1251

Confruntat cu sarcina - detectarea automată a paginii/textului/orice codificare. Sarcina nu este nouă și au fost deja inventate o mulțime de biciclete. In articol mica recenzie găsit pe net - plus o ofertă a mea, mi se pare, o soluție demnă.

1. De ce nu mb_detect_encoding()?

Pe scurt, nu merge.

Hai sa vedem:
// La intrare - text rusesc codificat în CP1251 $string = iconv("UTF-8", "Windows-1251", "S-a apropiat de Anna Pavlovna, i-a sărutat mâna, oferindu-i capul lui chel parfumat și strălucitor și s-a așezat calm jos pe canapea."); // Să vedem ce ne oferă md_detect_encoding(). Primul $strict = FALSE var_dump(mb_detect_encoding($string, array("UTF-8"))); // UTF-8 var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251"))); // Windows-1251 var_dump(mb_detect_encoding($string, array("UTF-8", "KOI8-R"))); // KOI8-R var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R"))); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "ISO-8859-5"))); // ISO-8859-5 var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R", "ISO-8859-5"))); // ISO-8859-5 // Acum $strict = TRUE var_dump(mb_detect_encoding($string, array("UTF-8"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "KOI8-R"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "ISO-8859-5"), TRUE)); // ISO-8859-5 var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R", "ISO-8859-5"), TRUE)); // ISO-8859-5
După cum puteți vedea, rezultatul este o mizerie completă. Ce facem când nu înțelegem de ce o funcție se comportă astfel? Așa e, căutăm pe google. Am găsit un răspuns grozav.

Pentru a risipi în sfârșit toate speranțele de a folosi mb_detect_encoding(), trebuie să intrați în sursele extensiei mbstring. Deci, suflecați-vă mânecile, să mergem:
// ext/mbstring/mbstring.c:2629 PHP_FUNCTION(mb_detect_encoding) ( ... // linia 2703 ret = mbfl_identify_encoding_name(&string, elist, size, strict); ...
Ctrl+clic:
// ext/mbstring/libmbfl/mbfl/mbfilter.c:643 const char* mbfl_identify_encoding_name(mbfl_string *string, enum mbfl_no_encoding *elist, int elistsz, int strict) ( const mbfl_encoding *encoding; encoding = el_encoding, elistszify , strict);...
Ctrl+clic:
// ext/mbstring/libmbfl/mbfl/mbfilter.c:557 /* * identifica codificarea */ const mbfl_encoding * mbfl_identify_encoding(mbfl_string *string, enum mbfl_no_encoding *elist, int elistsz, int strict) ( ...
Nu voi posta textul integral al metodei, pentru a nu înfunda articolul cu surse inutile. Cei interesați vor vedea singuri. Ne va interesa rândul numărul 593, unde se verifică dacă caracterul se potrivește codării:
// ext/mbstring/libmbfl/mbfl/mbfilter.c:593 (*filter->filter_function)(*p, filtru); dacă (filtru->steagul) ( rău++; )
Iată principalele filtre pentru chirilice cu un singur octet:

Windows-1251 (comentariile originale păstrate)
// ext/mbstring/libmbfl/filters/mbfilter_cp1251.c:142 /* toate astea sunt atât de urâte acum! */ static int mbfl_filt_ident_cp1251(int c, mbfl_identify_filter *filter) ( dacă (c >= 0x80 && c< 0xff) filter->steag = 0; altfel filtru->

KOI8-R
// ext/mbstring/libmbfl/filters/mbfilter_koi8r.c:142 static int mbfl_filt_ident_koi8r(int c, mbfl_identify_filter *filter) ( dacă (c >= 0x80 && c< 0xff) filter->steag = 0; else filter->flag = 1; /* nu este */ returnează c; )

ISO-8859-5 (totul este în general distractiv aici)
// ext/mbstring/libmbfl/mbfl/mbfl_ident.c:248 int mbfl_filt_ident_true(int c, mbfl_identify_filter *filter) ( return c; )
După cum puteți vedea, ISO-8859-5 returnează întotdeauna TRUE (pentru a returna FALSE, trebuie să setați filtru->flag = 1).

Când ne-am uitat la filtre, totul a căzut la loc. CP1251 nu se distinge de KOI8-R. ISO-8859-5 în general, dacă se află în lista de codificări, va fi întotdeauna detectat ca corect.

În general, eșuează. Este de înțeles - numai prin coduri de caractere este imposibil în cazul general să se afle codificarea, deoarece aceste coduri se intersectează în diferite codificări.

2. Ce oferă Google

Și Google dă tot felul de mizerie. Nici nu voi posta sursa aici, vedeți singur dacă doriți (eliminați spațiul după http://, nu știu cum să arăt textul nu ca link):

http://deer.org.ua/2009/10/06/1/
http://php.su/forum/topic.php?forum=1&topic=1346

3. Căutare Habr

1) din nou coduri de caractere: habrahabr.ru/blogs/php/27378/#comment_710532

2) dupa parerea mea, o solutie foarte interesanta: habrahabr.ru/blogs/php/27378/#comment_1399654
Pro și contra în comentariile de la link. Personal, cred că această soluție este redundantă doar pentru detectarea codificării - se dovedește a fi prea puternică. Definiția codificării din ea - ca efect secundar).

4. De fapt, decizia mea

Ideea a apărut în timpul vizualizării celui de-al doilea link din secțiunea anterioară. Ideea este următoarea: luăm un text mare rusesc, măsurăm frecvențele diferitelor litere și folosim aceste frecvențe pentru a detecta codificarea. Privind în viitor, voi spune imediat că vor exista probleme cu literele mari și mici. Prin urmare, postez exemple de frecvențe de litere (să-i spunem „spectru”) atât cu majuscule, cât și fără (în al doilea caz, am adăugat o literă și mai mare la litera mică cu aceeași frecvență și le-am șters pe toate cele mari) . În aceste „spectre” sunt decupate toate literele cu frecvențe mai mici de 0,001 și un spațiu. Iată ce am primit după procesarea „Război și pace”:

„spectru” cu majuscule și minuscule:
matrice ("o" => 0.095249209893009, "e" => 0.06836817536026, "a" => 0.067481298384992, "u" => 0.055995027400041, "0236817536026, "a" => 0.067481298384992, "u" => 0.055995027400041, "0236817536041, "023,0027400041; П "=> 0.0018574762967903," f "=> 0.0015961610948418," in "=> 0.0014044332975731," o "=> 0.0012623590130186," k "=> 0.0011804488387602," m "=> 0.001061932790165,)

Nu ține seama de majuscule și minuscule:
Array ("O" => 0.095249209893009, "O" => 0.095249209893009, "E" => 0.06836817536026, "A" => 0,067481298384992, "A" => 0.067481298384992, "și" = 0.055995027400041 , "Și" => 0.055995027400041, .... "C" => 0.0029893589260344, "C" => 0.0029893589260344, "щ" => 0.0024649163501406, "E" => 0.002252892226507, "E" => 0,002252892226507, "Ф" => 0,0015961610948418, "Ф" => 0,0015961610948418,)

Spectre în diferite codificări (chei matrice - coduri ale caracterelor corespunzătoare în codificarea corespunzătoare):

Mai departe. Luăm textul unei codări necunoscute, pentru fiecare codificare pe care o verificăm, găsim frecvența caracterului curent și adăugăm această codificare la „evaluare”. Codificarea cu cea mai mare evaluare este cel mai probabil codarea textului.

$encodings = array("cp1251" => necesită "specter_cp1251.php", "koi8r" => necesită "specter_koi8r.php", "iso88595" => necesită "specter_iso88595.php"); $enc_rates = array(); pentru ($i = 0; $i< len($str); ++$i) { foreach ($encodings as $encoding =>$char_specter) ( $enc_rates[$encoding] += $char_specter)]; ) var_dump($enc_rates);
Nici măcar nu încercați să rulați acest cod pe cont propriu - nu va funcționa. Vă puteți gândi la asta ca un pseudocod - am omis detaliile pentru a nu aglomera articolul. $char_specter este doar matricele la care se face referire în pastebin.

rezultate
Rândurile tabelului sunt codificarea textului, coloanele sunt conținutul matricei $enc_rates.

1) $str = „Text rusesc”;
0,441 | 0,020 | 0,085 | Windows-1251
0,049 | 0,441 | 0,166 | KOI8-R
0,133 | 0,092 | 0,441 | ISO-8859-5

Totul e bine. Codificarea reală are deja o evaluare de 4 ori mai mare decât restul - aceasta este pe un text atât de scurt. Pentru textele mai lungi, raportul va fi aproximativ același.


cp1251 | koi8r | iso88595 |
0,013 | 0,705 | 0,331 | Windows-1251
0,649 | 0,013 | 0,201 | KOI8-R
0,007 | 0,392 | 0,013 | ISO-8859-5

Hopa! Terci plin. Deoarece literele mari din CP1251 corespund de obicei literelor mici din KOI8-R. Și literele mici sunt folosite la rândul lor mult mai des decât cele mari. Deci definim șirul de majuscule în CP1251 ca KOI8-R.
Încercarea de a face acest lucru nu ține seama de majuscule și minuscule („spectre” nu ține seama de majuscule)

1) $str = „Text rusesc”;
cp1251 | koi8r | iso88595 |
0,477 | 0,342 | 0,085 | Windows-1251
0,315 | 0,477 | 0,207 | KOI8-R
0,216 | 0,321 | 0,477 | ISO-8859-5

2) $str = "STRING CAPSOM TEXT RUSĂ";
cp1251 | koi8r | iso88595 |
1,074 | 0,705 | 0,465 | Windows-1251
0,649 | 1,074 | 0,201 | KOI8-R
0,331 | 0,392 | 1,074 | ISO-8859-5

După cum puteți vedea, codificarea corectă conduce stabil cu „spectre” sensibile la majuscule (dacă șirul conține o cantitate mică de litere mari), și nu ține seama de majuscule. În cel de-al doilea caz, cu cele care nu țin cont de majuscule, liderul nu este atât de încrezător, desigur, dar destul de stabil chiar și pe șiruri mici. De asemenea, vă puteți juca cu greutățile literelor - faceți-le neliniare în raport cu frecvența, de exemplu.

5. Concluzie

Subiectul nu acoperă lucrul cu UTF-8 - nu există nicio diferență fundamentală aici, cu excepția faptului că obținerea codurilor de caractere și împărțirea șirului în caractere va fi ceva mai lungă/mai complicată.
Aceste idei pot fi extinse nu numai la codificări chirilice, desigur - întrebarea se află doar în „spectrele” limbilor/codificărilor corespunzătoare.

P.S. Dacă este foarte necesar/interesant, atunci voi posta a doua parte a unei biblioteci complet funcționale pe GitHub. Deși cred că datele din postare sunt destul de suficiente pentru a scrie rapid o astfel de bibliotecă și pentru a se potrivi propriilor nevoi - „spectrul” pentru limba rusă este prezentat, poate fi transferat cu ușurință în toate codificările necesare.

Să revenim la pagina noastră HTML pe care am creat-o în lecțiile anterioare și să setăm acum codificarea în care va fi stocat textul acesteia.

Aș dori să vorbesc despre două moduri prin care puteți schimba codarea textului. De regulă, le folosesc în practică și s-au dovedit bine.

Cea mai fiabilă modalitate de a schimba codarea textului este cu Programe Notepad++. De regulă, această metodă funcționează întotdeauna în mod fiabil și poate fi folosită pentru a rezolva cele mai dificile probleme.

1 cale. Folosind Notepad++

Deci, pentru a schimba codarea textului, avem nevoie de un special editor de text, care se numește notepad++.

Este gratuit și poate fi descărcat de pe acest site:

Deschideți pagina HTML folosind acest program și accesați meniul principal „Codări”.

Selectați codarea în care doriți să convertiți și salvați fișierul.

Asta e toată procedura. Programul este foarte bun și, spre deosebire de alte alternative, schimbă fără greșeală codificarea.

2 sensuri. Folosind editorul de cod universal Dreamweaver.

Dacă lucrați în editorul de cod universal al Dreamweaver, există și opțiunea de a specifica codarea în care va fi redat textul.


Puteți face acest lucru și folosind meniul principal „Editare - Proprietăți pagină”.


Apoi, în categoria „Nume / Codificare”, selectați codarea de care aveți nevoie. Cel mai adesea aceasta va fi codificare Unicode (UTF-8).

Când creați un nou document html, această metodă funcționează bine, dar dacă modificați codificarea unui fișier existent, atunci este mai bine să utilizați prima metodă. În acest caz, funcționează mai bine.

Efectuați această operațiune pe computer.

Dar, specificarea codificării textului pentru pagina html nu este suficientă. Pentru funcționarea normală, trebuie să faceți încă un lucru: spuneți browserului în ce codificare este scris textul.

Dintr-o dată, un script simplu a încetat să funcționeze. Sarcina scriptului este de a obține o pagină HTML (dintr-un joc de browser) și de a prelua datele folosind expresii regulate. Pentru mine, ca începător, acest eveniment a provocat nedumerire și o ușoară panică: la urma urmei, totul mergea încă ieri! Ce s-a întâmplat?
A trebuit să înțeleg temeinic activitatea unor funcții PHP.

Codul era destul de primitiv:

$pattern = ; $url = „http://www.heroeswm.ru/pl_info.php?id=($id)”; $html = file_get_contents ($url ) ; preg_match ($pattern , $html , $match ) ; if (isset ($match [ 1 ] ) ) echo $match [ 1 ] ; else echo "nu a fost găsit";

$pattern = "#Scrie o scrisoare(.*)Nivel de luptă#este"; $url = "http://www.heroeswm.ru/pl_info.php?id=($id)"; $html = file_get_contents($url); preg_match($pattern, $html, $match); if (isset($match)) echo $match; else echo „nu a fost găsit”;

Obținerea datelor și analizarea cu o expresie regulată simplă.
Trebuie să spun că acest cod este rezultatul unei ușoare modificări. În versiunea originală, expresia regulată a căutat etichete HTML. Dar acum trebuia să găsesc o bucată între două fraze în rusă. Am adăugat cuvinte rusești la șablonul de căutare și această schimbare a devenit critică.

Și acum în ordine.
Site-ul de joc www.heroeswm.ru oferă pagini în codificare win-1251. Am codare pe serverul meu UTF-8, deci toate scripturile sunt în UTF-8 fără BOM.
Scriptul original cu căutare prin etichete HTML a funcționat corect, în ciuda diferenței de codificări, dar când am adăugat caractere chirilice la șablonul de căutare, am încetat să caut și să găsesc. În sarcina mea, ar fi foarte ușor să dau deoparte problema și să ridic un alt șablon - fără cuvinte rusești, dar în cele mai multe cazuri acest lucru este imposibil. Așa că am decis să o fac corect: care este diferența fundamentală dintre codificări de ce sună munca incorectă a expresiilor regulate, și în același timp ce funcții sunt afectate din cauza diferenței dintre codificări și a modului de ocolire.

Pentru a obține datele, am folosit funcția file_get_contents(), care are următoarea sintaxă:

şir file_get_contents( şir$filename) , unde $filename este numele fișierului citit.
Returnează un șir sau bool(false) dacă datele nu au fost primite cu succes.

Cea mai evidentă diferență de codificare win-1251și UTF-8 este numărul de caractere care pot fi codificate cu ele. Primele (și toate ca acestea) sunt supuse doar 255, deoarece fiecare caracter este codificat de un octet.

Cu ajutorul celui de-al doilea, puteți transfera un set cu adevărat uriaș de caractere, inclusiv litere ale alfabetelor naționale, litere arabe și hieroglife. O astfel de extindere a setului de caractere se realizează datorită faptului că caracterele sunt codificate nu cu unul, ci cu doi (pentru majoritatea caracterelor) sau mai mulți (până la patru) octeți. Prin urmare, codificarea UTF-8(și altele similare) sunt numite multi- sau multi-octeți, spre deosebire de cele cu un singur octet, cum ar fi win-1251.

Cu un set atât de extins de semne, UTF-8 nu numai că va permite utilizarea literelor de diferite alfabete pe un site, dar va oferi și o anumită garanție că site-ul în limba rusă va fi afișat corect chiar și acolo unde există codificări cu suport chirilic ( win-1251, KOI8-R, CP866, ISO 8859-5 etc.) nici măcar nu bănuiți: în Japonia, Coreea, țările arabe etc. Prețul pentru o astfel de versatilitate va fi o greutate ceva mai mare a caracterelor în timpul stocării și, în consecință, un timp mai lung pentru procesarea lor prin funcții șir. PHP. Apropo, în majoritatea cazurilor nu vor funcționa corect. Aceasta a fost problema pe care am întâlnit-o: expresia regulată a unui scenariu scris UTF-8, pur și simplu nu am putut găsi corect subșirul de care aveam nevoie, inclusiv caracterele chirilice, pe pagina obținută de pe site în Windows-1251.

Este logic să presupunem că site-urile care vor folosi doar alfabetul chirilic și latină o vor face UTF-8 la nimic, iar analizatorul simplu considerat destul de bine „trăit” în win-1251, dar există situații în care nu este necesar să ne împrietenești cu aceste codificări și utilizare funcții șir PHP pur și simplu nu ieșiți, de exemplu, atunci când dezvoltați un proiect în UTF-8.

Ce a cauzat comportamentul incorect al funcțiilor șir?

După cum am menționat deja, principala diferență dintre codificări este lungimea caracterelor. Prin urmare, apar probleme atunci când se utilizează funcții în care acestea lucrează cu caractere ca și cu octeți, iar valorile sunt returnate și în octeți (acest lucru este valabil pentru o codificare pe un singur octet: un caracter este egal cu un octet).

De exemplu, funcția

substr ("Verificare", 0, 5); // text în codificare UTF-8

substr("Verificare", 0, 5); // text în codificare UTF-8

va returna „Pr�” în loc de „Prove” așteptat: în UTF-8 Caracterele chirilice sunt codificate în doi octeți, drept urmare vedem „krakozyabr” - doar primul octet al caracterului „o”.

Astfel, în cele mai multe cazuri, pentru a lucra cu șiruri în UTF-8 va necesita utilizarea unor funcții speciale (de exemplu, din extensia PHP mbstring), și uneori ambele (de exemplu, pentru a trece dimensiunea șirului în octeți în antetul HTTP, va trebui să lăsați strlen() , iar pentru a număra numărul de caractere, va trebui să adăugați mb_strlen()).

Sintaxa funcțiilor utilizate frecvent, care poate fi nevoie să fie înlocuite cu funcții dintr-o extensie PHP mbString:

int strlen( şir$șir) - Returnează lungimea șirului sau 0 dacă șirul este gol.

int strpos( şir$haystack , amestecat$needle) - returnează poziția primei apariții a șirului $needle în subșirul $haystack, sau FALS dacă nu este găsit.

stripos este similar cu funcția anterioară, doar căutarea nu face distincție între majuscule și minuscule.

şir substr( şir$șir , int$start [, int $lungime]) - vă permite să selectați un subșir pornind de la poziția specificată a caracterului, iar atunci când specificați al treilea parametru - o anumită lungime.

Analogii lor sunt proiectați să funcționeze în codificări multibyte: mb_strlen , mb_strpos , mb_stripos și mb_substr .

Desigur, există multe mai multe funcții pentru a lucra cu text. Le-am inclus doar pe cele mai populare.

Funcțiile pentru lucrul cu expresii regulate, concepute pentru a căuta un subșir (subșiruri) care se potrivesc cu masca specificată de o expresie regulată, se deosebesc.

int preg_match( şir$pattern , şir$subiect , matrice&$potriviri)

int preg_match_all( şir$pattern , şir$subiect matrice&$potriviri) .

Textul $subiect se potrivește cu $patternul specificat de expresia regulată. Rezultatul căutării este scris în variabila $match. Funcția returnează numărul de potriviri găsite cu modelul, în cazul unei erori va reveni FALS.

Pentru a utiliza codificări pe mai mulți octeți pentru potrivirea modelelor expresii obisnuite, va trebui să le adăugați modificatorul /u sau să utilizați grupul de funcții mb_ereg*.

Ce să fac?

Soluția care a venit prima este să recodificați UTF-8 primit în win-1251 date - părea incomod. La urma urmei, după recodificare, toate funcțiile obișnuite vor trebui înlocuite cu unele speciale pentru a lucra UTF-8, sau încercați să utilizați modificatorul /u (cu privire la viitor, voi spune că vă permite să lucrați cu șiruri de caractere în codificări pe un singur octet, „ca și cu șiruri de caractere UTF-8', dar nu este potrivit pentru șiruri în UTF-8). În exemplul meu, există doar un singur preg_match() , dar în practică acest lucru se întâmplă rar.

Deci răsturn problema: vreau să folosesc funcțiile normale preg_match() și, pentru a face asta, voi transcoda nu șirul primit, ci modelul de căutare folosind iconv() .

Sintaxa funcției:
şir iconv($in_charset, $out_charset, $str) - Convertește șirul $str din codificarea $in_charset la codificarea $out_charset. Returnează textul recodat fără a afecta variabila originală.

Funcţie returnează un șir în noua codificare, dar nu modifică codificarea șirului în sine. Asa de

$pattern = "#Scrie o scrisoare(.*)Nivel de luptă#este"; iconv("UTF-8", "WINDOWS-1251", $pattern); // $pattern rămâne în codificarea originală preg_match($pattern, $html, $match);

nu va funcționa - $pattern a rămas în codificarea originală UTF-8. Trebuie să atribuiți rezultatul iconv unei variabile:

$pattern = „#Scrie o scrisoare(.*)Nivel de luptă#este”; $pattern = iconv("UTF-8" , "WINDOWS-1251" , $pattern ) ; preg_match ($pattern , $html , $match ) ;

$pattern = "#Scrie o scrisoare(.*)Nivel de luptă#este"; $pattern = iconv("UTF-8", "WINDOWS-1251", $pattern); preg_match($pattern, $html, $match);

Acum, căutarea funcționează corect, dar dă doar krakozyabry solid browserului. Ei bine, aici știu deja ce să fac: trebuie să recodificați rezultatul într-o codificare funcțională UTF-8. Și apoi a ieșit la suprafață al doilea punct, care nu mi-a fost evident, deși dacă aș fi avut mai multă experiență, probabil că nu aș fi creat dificultăți: de ce iconv () recodează unele variabile, dar nu altele?

Variabila $matches este o matrice și am încercat să scap cu o recodificare a iconv($match) . Mă uit din nou la descrierea sintaxei funcției: bine, desigur, toți parametrii trebuie să fie șiruri de caractere, și nu matrice. Adică, este necesar să parcurgeți toate valorile matricei care trebuie recodate și să le convertiți codificarea dorită. În exemplul meu, nu am iterat prin matrice, pentru că eram interesat de o singură valoare, și nu de întreaga matrice. L-am specificat ca parametru al funcției iconv().

Iată cu ce am ajuns:

// setează codarea implicită setlocale(LC_ALL, "ru_RU.UTF-8" ); antet( „Tip de conținut: text/html; set de caractere=UTF-8”) ; $pattern = „#Scrie o scrisoare(.*)Nivel de luptă#este”; $pattern = iconv("UTF-8" , "WINDOWS-1251" , $pattern ) ; $url = „http://www.heroeswm.ru/pl_info.php?id=993353”; $html = file_get_contents ($url ) ; preg_match ($pattern , $html , $match ) ; if (isset ($match [ 1 ] ) ) echo $match [ 1 ] = iconv ("WINDOWS-1251" , "UTF-8" , $match [ 1 ] ) ; else echo "nu a fost găsit"; ?>

Articolul a fost scris de bunul meu prieten. Ea este angajată în scrierea și verificarea textelor, programarea în PHP este mai mult din hobby-ul ei. În blogul meu, ea corectează toate publicațiile, iar aceasta a fost cadoul ei pentru mine pentru a 2-a aniversare a blogului.

Publicații similare nu au fost găsite.