Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP] Wczytanie pliku billingu w text
pianta_d
post 30.11.2011, 18:10:30
Post #1





Grupa: Zarejestrowani
Postów: 176
Pomógł: 18
Dołączył: 5.01.2007

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


Witam

Stanąłem przed problemem wczytania pliku z bilingiem telefonicznym.
Na późniejszym etapie będę wrzucał to do bazy, ale z tym to nie ma żadnego problemu, natomiast nie wiem jak w ogóle się do tego zabrać.
Plik bilingu ma straszną strukturę.

Przykładowy plik bilingu

Takich stron może być kilkanaście. Oddzielone są od siebie liniami ze znaku "-"
W kolumnie połączenie mogą być inne wpisy niż "lokalne" (ale to już nie jest istotne)

Nie będę się rozpisywał co musi być w skrypcie, aby później wczytać to do bazy.
Proszę o wskazówki.

Pozdrawiam
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 8)
nospor
post 30.11.2011, 18:13:59
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No coż, bez wyrażeń się raczej nie obejdzie.

Wydaje mi się, że najlepiej najpierw rozbić plik na konkretne bilingi. Skoro rodzielone one będą --------- to użyć do tego można preg_split()
Mając już konkretny biling, pobierać informacje z niego będziesz przy pomocy preg_match().


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
abort
post 30.11.2011, 21:07:12
Post #3





Grupa: Zarejestrowani
Postów: 590
Pomógł: 107
Dołączył: 25.10.2011

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


Etam, od razu "rozbijać". Zakładam, że interesują nas TYLKO rozmowy. A wszystkie rozmowy (i tylko rozmowy, bez podsumowań pokaże jeden preg_match na [0-9\ ][0-9]:[0-9][0-9]:[0-9][0-9] (uwaga na dołożoną spację w pierwszych [] exclamation.gif!)

Potem tylko rozbić na pola (ciut więcej zabawy będzie z czasem) i wrzucać do bazy.

Oczywiście nagiąłem założenie: powinien nas interesować także numer telefonu, z którego te rozmowy zostały przeprowadzone: zakładam, że to jest to wyiksowane pole tuż przed zestawieniem. Tu wystarczy nawet explode.
Go to the top of the page
+Quote Post
pianta_d
post 30.11.2011, 22:55:51
Post #4





Grupa: Zarejestrowani
Postów: 176
Pomógł: 18
Dołączył: 5.01.2007

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


Póki co napisałem

  1. $plik = file('plik.txt');
  2. for($i = 55, $x = count($plik); $i < $x; $i++)
  3. {
  4. $str = $plik[$i];
  5. $chars = preg_split('/ /', $str, 0, PREG_SPLIT_NO_EMPTY);
  6. if ($i==55) // nr lini, w której przechowywane są dane do nagłówka
  7. {
  8. echo '<br>Dane bilingowe za okres od '.str_replace('r.','',$chars[7]).' do '.str_replace('r.','',$chars[9]).' z nr tel.
  9. '.$chars[12],$chars[13],$chars[14].'<BR><br>';
  10. }
  11. if ($i >= 60)
  12. {
  13. $ile_kropek=strstr($chars[0], ".");
  14. if ($ile_kropek==TRUE)
  15. {
  16. $data_rozmowy=$chars[0];
  17. echo 'Wstawiamy w pierwszą kolumnę datę, czyli: <b>'.$data_rozmowy.'</b>';
  18. echo ' O godzinie '.$chars[1];
  19. echo ' Na numer '.$chars[2];
  20. echo ' Rodzaj połączenia '.$chars[3].'<br>';
  21. }
  22. else
  23. {
  24. echo 'Kropek brak, ale wstawiamy ze zmiennej, czyli: '.$data_rozmowy.'<br>';
  25. }
  26. }
  27. }

Kod jest z moimi tekstami, które może sa prozaiczne, ale lubię prostotę smile.gif

Ładnie dzieli mi na odpowiednie komórki, które później będą dodawane do bazy.

Cytat
Etam, od razu "rozbijać". Zakładam, że interesują nas TYLKO rozmowy


Generalnie chodzi mi o wszystkie dane zawarte w pliku

Dziękuje za zainteresowanie.
Temat dalej będzie kontynuowany.

Pozdrawiam
Go to the top of the page
+Quote Post
Uriziel01
post 1.12.2011, 10:47:55
Post #5





Grupa: Zarejestrowani
Postów: 307
Pomógł: 37
Dołączył: 9.11.2010
Skąd: Zielona Góra

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


Tak może być ? Kod jest zrobiony 'na kolanie', na pewno można to zrobic jeszcze tysiąc razy lepiej i pewnie zawiera jeszcze 500 błędów ale działa smile.gif Mam dzisiaj dobry humor.
EFEKT:


KOD:
  1. <?PHP
  2. $last_date = NULL;
  3. $plik = file_get_contents('plik.txt');
  4. $plik = get_string_between($plik, 'za okres od','Razem');
  5. $plik = explode("\r\n",$plik);
  6. $numer_linii = substr($plik[0], strpos($plik[0], 'nr linii: ') + 10);
  7. $plik = array_slice($plik,5,-2);
  8. foreach ($plik AS $main_index => &$rozmowa)
  9. {
  10. $rozmowa = ltrim ( $rozmowa, " ");
  11. $rozmowa = explode(" ",$rozmowa);
  12. foreach ($rozmowa AS $index => $pole)
  13. {
  14. if (strlen($pole) < 2)
  15. {
  16. unset($rozmowa[$index]);
  17. }
  18. }
  19. $rozmowa = array_values($rozmowa);
  20. if (strpos($rozmowa[0], " ") !== false)
  21. {
  22. $result[$main_index]['date'] = substr($rozmowa[0], 0, strpos($rozmowa[0], " "));
  23. $result[$main_index]['time'] = substr($rozmowa[0], strpos($rozmowa[0], " "));
  24. }
  25. else
  26. {
  27. if (strpos($rozmowa[0],'.') === false)
  28. {
  29. $result[$main_index]['date'] = $last_date;
  30. $result[$main_index]['time'] = $rozmowa[0];
  31. }
  32. else
  33. {
  34. $result[$main_index]['date'] = $rozmowa[0];
  35. }
  36. }
  37. $last_date = $result[$main_index]['date'];
  38. $result[$main_index]['phone_number'] = $rozmowa[1];
  39. $result[$main_index]['call_type'] = $rozmowa[2];
  40. $result[$main_index]['call_time'] = $rozmowa[3];
  41. $result[$main_index]['netto'] = $rozmowa[4];
  42. $result[$main_index]['brutton'] = $rozmowa[5];
  43. }
  44. var_dump($result);
  45. echo 'NR linii:' . $numer_linii;
  46. function get_string_between($string, $start, $end)
  47. {
  48. $string = " ".$string;
  49. $ini = strpos($string,$start);
  50. if ($ini == 0) return "";
  51. $ini += strlen($start);
  52. $len = strpos($string,$end,$ini) - $ini;
  53. return substr($string,$ini,$len);
  54. }
  55. ?>


Ten post edytował Uriziel01 1.12.2011, 10:49:06
Go to the top of the page
+Quote Post
abort
post 1.12.2011, 16:23:57
Post #6





Grupa: Zarejestrowani
Postów: 590
Pomógł: 107
Dołączył: 25.10.2011

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


Potestuj wyrażenia regularne - to skraca kod:

  1. $rozmowy = array ();
  2. $rozm_idx = 0;
  3. print "<pre>\n"; // dla wygody debugowania
  4. $handle=fopen ("billing.txt", "r"); // zakładamy że plik istnieje,więc brak obsługi błędów
  5. while (!feof ($handle)) {
  6. $line = fgets ($handle, 200);
  7. if (preg_match ('@za okres od\s+([0-9.]+)r. do\s+ ([0-9.]+)r.\s+nr linii: ([0-9x\ \(\)]+).*@', $line, $match)) {
  8. $rozmowy['header']['okres_start']=$match[1];
  9. $rozmowy['header']['okres_end']=$match[2];
  10. $rozmowy['header']['phone_number']=$match[3];
  11. }
  12. if (preg_match ('@([0-9 ]{2}.[0-9]{2}){0,1}\s([0-9 ]{2}.[0-9]{2}.[0-9]{2})\s([0-9x\ \(\)]+)\s+(\w+)\s+([0-9 ms]+)\s+([0-9.,]+)\s+([0-9.,]+)@', $line, $match)) {
  13. $rozm_idx++;
  14. if ($match[1] == '') {
  15. $rozmowy[$rozm_idx]['date']=$rozmowy[$rozm_idx-1]['date'];
  16. } else {
  17. $rozmowy[$rozm_idx]['date']= $match[1];
  18. }
  19. $rozmowy[$rozm_idx]['time']= $match[2];
  20. $rozmowy[$rozm_idx]['phone_number']= $match[3];
  21. $rozmowy[$rozm_idx]['call_type']= $match[4];
  22. $rozmowy[$rozm_idx]['call_time']= $match[5];
  23. $rozmowy[$rozm_idx]['netto']= $match[6];
  24. $rozmowy[$rozm_idx]['brutto']= $match[7];
  25. }
  26. }
  27. fclose ($handle);
  28.  
  29. print_r ($rozmowy); // debug :)
  30.  


Starałem się intuicyjnie nazywać zmienne. Potestuj.
Go to the top of the page
+Quote Post
pianta_d
post 2.12.2011, 19:53:11
Post #7





Grupa: Zarejestrowani
Postów: 176
Pomógł: 18
Dołączył: 5.01.2007

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


Dziękuje Wam wszystkim.
Cóż, dostałem gotowca i się z tego cieszę, aczkolwiek teraz muszę zrozumieć wyrażenia regularne.
Lektura z internetu jest troszkę chaotyczna i jak na moje lata mało zrozumiała.

Dziękuję jeszcze raz za zainteresowanie i odwdzięczam się jak tylko mogę.

--- EDIT ---

Zauważyłem jeden problem w wyrażeniu regularnym, które napisał @abort. (chłopak nie wiedział, że taka może być sytuacja - w załączonym pliku tego nie ma)
Przy typie połączenia (w pliku mogą być wpisy: "lokalne","KRAKÓW","PLUS GSM", itp.) nie wczytuje połączeń, gdzie typ składa się z dwóch członów, czyli z trzech przytoczonych przykładów wczyta dwa pierwsze wiersze, a pominie "PLUS GSM".

Dzisiaj już siły mi brak, ale jutro siądę nad tym i będę mógł przy okazji poćwiczyć to czego się uczyłem od wczoraj.

Pozdrawiam

---- EDIT ----

Siedzę nad wyrażeniem i przerobiłem to co napisał @abort
  1. preg_match ('@([0-9 ]{2}.[0-9]{2}){0,1}\s([0-9 ]{2}.[0-9]{2}.[0-9]{2})\s([0-9x\ \(\)]+)([a-zA-Z ]{1,}[^s0-9])([0-9 sm]+)\s+([0-9.,]+)\s+([0-9.,]+)@', $line, $match)

wczytuje mi już dwuczłonowe typy połączeń jednak coś pomija.
Podpinam do wczytania plik, na którego końcu jest podsumowanie, gdzie napisano, że abonent wykonał 695 połączeń, a mój preg_match wczytuje mi 647.

Proszę o pomoc z tym wyrażeniem.

Ten post edytował pianta_d 2.12.2011, 19:53:44
Go to the top of the page
+Quote Post
zegarek84
post 2.12.2011, 21:26:56
Post #8





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


na pewno Ci pomija "KRAKÓW" gdyż nie widzę polskich znaków w zestawie znaków...

co do wyrażeń regularnych jest wiele dobrych stron (także manual PHP)... z polskich artykułów co na szybko przychodzi mi do głowy i nie jest najgorszy to:
Wyrażenia regularne PCRE w PHP Tutorial - w nowej wersji PHP dodali jeszcze kilka w sumie zbędnych szczegółów...


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
abort
post 2.12.2011, 23:58:58
Post #9





Grupa: Zarejestrowani
Postów: 590
Pomógł: 107
Dołączył: 25.10.2011

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


Zamiast (\w+) daj coś, co zadziała dla dwóch wyrazów:
Kod
(\w+(\s{1}\w+){0,1})


Tylko indeksy Ci się rozjadą, użyj:
  1. $rozmowy[$rozm_idx]['call_time']= $match[6];
  2. $rozmowy[$rozm_idx]['netto']= $match[7];
  3. $rozmowy[$rozm_idx]['brutto']= $match[8];

Nie ma indeksu "$match[5]".
A precyzyjniej: jest, ale nie do końca pokazuje to, co chcesz. A co pokazuje? Sprawdź, zapewne dojdziesz, dlaczego.

P.S.
W "([0-9x\ \(\)]+)" usuń znak "x" - on był po to, by łapać Twoje wyiksowane (zaciemnione) numery - normalnie tam powinny być cyfry, spacje i nawiasy, iksa tam nie będzie chyba nigdy.

Ten post edytował abort 3.12.2011, 00:02:05
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 - 07:09