Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Wyrażenia regularne problem
adamp359
post 27.11.2012, 09:30:28
Post #1





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 7.06.2012

Ostrzeżenie: (0%)
-----


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.

Ten post edytował adamp359 27.11.2012, 09:31:17
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 5)
b4rt3kk
post 27.11.2012, 12:20:57
Post #2





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


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;


Ten post edytował b4rt3kk 27.11.2012, 12:21:18


--------------------
Jeśli pomogłem, kliknij proszę 'pomógł'. Dzięki.
Go to the top of the page
+Quote Post
adamp359
post 27.11.2012, 13:50:43
Post #3





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 7.06.2012

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
cudny
post 27.11.2012, 14:47:59
Post #4





Grupa: Zarejestrowani
Postów: 387
Pomógł: 66
Dołączył: 31.03.2005
Skąd: Kielce

Ostrzeżenie: (0%)
-----


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

Ten post edytował cudny 27.11.2012, 14:58:25


--------------------
..::: Jak pomogłem to kliknij pomógł. Tak rzadko używacie tej opcji :( :::..
Go to the top of the page
+Quote Post
adamp359
post 27.11.2012, 16:38:53
Post #5





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 7.06.2012

Ostrzeżenie: (0%)
-----


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

Ten post edytował adamp359 27.11.2012, 20:13:25
Go to the top of the page
+Quote Post
cudny
post 27.11.2012, 21:22:13
Post #6





Grupa: Zarejestrowani
Postów: 387
Pomógł: 66
Dołączył: 31.03.2005
Skąd: Kielce

Ostrzeżenie: (0%)
-----


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ść )


--------------------
..::: Jak pomogłem to kliknij pomógł. Tak rzadko używacie tej opcji :( :::..
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 08:09