Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyrażenia regularne problem
Forum PHP.pl > Forum > PHP
adamp359
Witam
Mam problem z konstruowaniem wyrażenia regularnego które będzie szukać danego słowa.

  1. $tresc = 'Próby absorpcyjny najbardziej gorąco oczek i dad as';
  2.  
  3. $dane = explode(' ',$tresc);
  4.  
  5. $z = 0;
  6. $ile = count($dane)-1;
  7. for($i = 0; $i<= $ile; $i++)
  8. {
  9. //echo $i;
  10. $slowo = trim($dane[$i]);
  11. if (!empty($slowo))
  12. {
  13. $wartosc = preg_match('/{.*'.$slowo.'.*}/', $synonimy, $out);
  14. print_r($out);
  15. if ($wartosc == 1)
  16. {
  17. $tekssyn .= $out[0].' ';
  18. }
  19. else
  20. {
  21. $tekssyn .= $slowo.' ';
  22. }
  23. }
  24.  
  25. }
  26.  
  27. echo $tekssyn;

Jakie zadanie ma skrypt ze zmiennej $tresc rozbijamy na wyrazy następnie w pętli for sprawdzamy czy dany wyraz znajduje się w pliku txt
dane w pliku txt wyglądają tak: (zmienna $synonimy)

{absolutyzm|monarchiaabsolutna|władzaabsolutna}
{absolwent|wychowanek}
{absorbent|pochłaniacz|substancjapochłaniająca}
{absorber|aparatabsorpcyjny}
{absorbować|asymilować|przyswajać|wchłaniać|frapować|pochłaniać|zajmować|zaprząt
ać}
{absorbując|asymilując|przyswajając|wchłaniając|frapując|pochłaniając|zajmując|z
aprzątając}
{absorbujący|chłonny|wchłaniający}
{absorpcja|pochłanianie|wchłanianie}


Problem polega na tym iż $wartosc = preg_match('/{.*'.$slowo.'.*}/', $synonimy, $out); sprawdza mi czy występuje dany znak lub ciąg na przykład szukamy litery "i" to jeśli w bazie będzie wyżej wyraz "interpretacja" to zostanie on zakwalifikowany. Druga sprawa jeśli skrypt znajdzie już dane słowo w bazie chce aby zamiast niego pojawiło się cały ciąg w klamrach na przykład {absorbujący|chłonny|wchłaniający} (ale to niby działa)

Trzecia sprawa to coś co najbardziej mnie martwi obciążenie serwera podczas szukania słów baza w txt ma prawie 3MB jak rozwiązać ten problem ma ktoś jakiś pomysł za wszystkie sugestie będę bardzo wdzięczny bo morduje się już z tym 3 dni.

Aha próbowałem także takiego wyrażenia regularnego $wartosc = preg_match('/\{.*[\{|\|]'.$slowo.'.*\}/', $synonimy, $out); lecz w tym przypadku znajduje mi tylko wyrazy które zaczynają się na daną literę lub ciąg liter a ja nadal chce konkretnie cały wyraz aby się zgadzał.

Jeszcze raz bardzo proszę o pomoc z góry dzięki.
b4rt3kk
Jeśli plik jest duży to siłą rzeczy jego wczytanie w całości zajmie dłuższą chwilę. Jeśli masz taką możliwość oprzyj skrypt o bazę danych SQL. Np. stwórz taką tabelę:

Kod
id | synonimy
===+=========
1 |  absolutyzm|monarchiaabsolutna|władzaabsolutna
2 | absolwent|wychowanek
3 | absorbent|pochłaniacz|substancjapochłaniająca


I teraz możesz szukać synonimów:

  1. $tresc = 'Próby absorpcyjny najbardziej gorąco oczek i dad as';
  2.  
  3. $dane = explode(' ',$tresc);
  4.  
  5. $z = 0;
  6. $ile = count($dane)-1;
  7. for($i = 0; $i<= $ile; $i++)
  8. {
  9. //echo $i;
  10. $slowo = trim($dane[$i]);
  11. if (!empty($slowo))
  12. {
  13. $query = "SELECT * FROM tablica WHERE synonimy LIKE '%$slowo%'";
  14. // wykonanie zapytania, przetworzenie i wyświetlenie wyników
  15. }
  16.  
  17. }
  18.  
  19. echo $tekssyn;
adamp359
Powiem tak testowałem wczoraj i na bazie danych lecz zapytanie które mi podałeś nie spełnia oczekiwań mojego pytania ponieważ zapytanie będzie nadal wyszukiwało mi nawet pojedyncza literę z całego słowa na przykład "i" w słowie "oczekiwać" zostanie zatwierdzone jako zgodne.

dałem takie coś
synonimy LIKE '{$slowo|%' or synonimy LIKE '%|slowo| %' or synonimy LIKE '%|slowo}'

też takie zapytanie trochę trwa (teraz jestem w pracy i nie pamiętam ile było rekordów w bazie) ale chyba około 40tys albo 400tys nie pamiętam nie pamiętam dam znać wieczorem.

Ty w przykładzie nie dałeś { } na końcu i na początku może to i dobry pomysł tylko trzeba by było dać właśnie | na koniec i początek tak to wystarczy jeden LIKE
synonimy LIKE '%|slowo| %'
ale i tak później muszę je zmienić podczas wyświetlania na { } bo lipa będzie wink.gif

A Sqlite ? Chciałbym aby skrypt był "mobilny" bardziej między serwerami aby wystarczyło tylko przerzucenie plików.

Ma ktoś jeszcze jakieś sugestie ?
Jestem skłonny zapłacić za rozwiązanie tego problemu tylko proszę podać kwotę kto chętny na PW zapraszam.
cudny
Musisz dać zrzut bazy danych gdzieś aby sobie uzupełnić i przeprowadzić testy.
Aby było najwydajniej to warto by pokombinować z zaindexowaniem każdego wyrazu, można spróbować coś takiego - zwiększa to ilość wyrażeń wewnątrz tabeli, ale daje nam pewność szybszego działania.

struktura bazy:
  1.  
  2. id - PRIMARY INDEX
  3. word - UNIQUE INDEX
  4. synonyms - FULL text
  5.  
  6. id | word | synonyms
  7. 1 | absolutyzm | monarchiaabsolutna,władzaabsolutna
  8. 2 | monarchiaabsolutna | absolutyzm,,władzaabsolutna
  9. 3 | władzaabsolutna | absolutyzm,monarchiaabsolutna

  1. $find = 'władzaabsolutna';
  2. $find = mb_strtolower($find);
  3. $query = 'select * from table where word = "'.$find.'" limit 1';
  4.  


jak dostaniesz wynik w tablicy to dajesz:

  1. $result = '{'.str_replace(',','|',$query['synonyms']).'|'.$query['word'].'}';
  2. echo $result;


Można też wszystko zaindexować w pllu full text ale ja nie jestem jednak do końca przekonany do takiego rozwiązania, poza tym działać będzie tylko na silniku myisam, który jest wypierany przez innodb
Jeśli interesuje cię full text search odsyłam do http://www.databasejournal.com/features/my...cle.php/1578331


Z drugiej strony mysql nie jest chyba tutaj najlepszym rozwiązaniem.
Taką strukturę danych jak zaproponowałem można zaimplementować w bazach nosql jak, np. mongodb - myślę, że było by to najfajniejsze rozwiązanie smile.gif
adamp359
Dzięki Cudny podsunąłeś mi pomysł zrobię relację między tabelami i będę wyszukiwał tylko po jednym polu dodam indexy mam nadzieje że będzie to szybko działać ale będzie dużo wiecej danych


---------------------- EDIT
Zrobiłem tak jak mówiłem relację miedzy tabelami i lata jak głupie
dzieki jeszcze raz za zainteresowanie smile.gif
cudny
Na indexach nie ma możliwości aby to nie hulało jak trzeba, ale nadal obstawiam jednak noSQL, a przede wszystkim MongoDB, do tego jeśli chcesz postawić na wydajność to użył bym do tego nginx ( apache ostatnio mi nie podchodzi właśnie o wydajność )
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.