Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]preg_match - nie potrafie sformułować
Forum PHP.pl > Forum > Przedszkole
majesgrudziadz
Witam nie potrafię sformułować zapytania preg_match może ktoś pomóc :

String który posiadam zawiera fragment:

"isWinner": 1, "credits": 105331, "markOfMastery": 3, "

jest jeszcze przed nim pełno różnych informacji a zależy mi na tym aby wyciągnąć to co jest po słowie

"credits": a przed wyrażeniem , "

czyli preg_match powinien mi wyświetlić

105331 w innych przypadkach może to być 0 lub 340 lub 104322334

proszę o pomoc w sformułowaniu zapytania do preg_match aby szukało mi wartość między wyrazami

  1. $szukam_credits = '/(credits": ).*[0-9], "/';


kombinuję z takim wyrażeniem ale znajduje mi :

Array ( [0] => credits": 105331, "markOfMastery": 3, "............ reszta ciągu

nie wiem jak zakończyć na ," i wyświetlić same cyfry
CuteOne
Hmmm ten kod wygląda jak JSON lub CSV. Podaj tu początek stringu

ps. w między czasie poczytaj o json_* i parsecsv() (tak to się chyba zwie)
majesgrudziadz
to nie jest csv to jest otwarty w nontatniku plik powtorki gry i pierwsze 50000 znaków to informacje statystyczne więc na początku wyciągam te 50000 znaków następnie chcę powyciągać to co mnie interesuje.

podałem przykład credits

nikt nie potrafi pomóc ?

bo ja już się powoli poddaje sad.gif
CuteOne
Skoro chcesz pomocy to wykonaj prostą rzecz, o którą prosiłem.
szalek01
  1. $data = '"isWinner": 1, "credits": 105331, "markOfMastery": 3, isWinner": 1, "credits": 2312, "markOfMastery": 3, "';
  2. preg_match_all('|"credits": ([0-9]+)|',$data,$r);
  3. echo $data;
  4. echo '<br/>';
  5. echo '<pre>';
  6. var_dump($r);
  7. echo '</pre>';

z json'em jest łatwiej smile.gif
-Bebok-
  1. if( preg_match('/"credits": (\d+)/',$string,$match) ) {
  2. $credits = $match[1];
  3. }


Przy czym znacznie szybsze od regexpa na stringu o 50,000 znakach będzie coś takiego:

  1. $credits = substr($string, strpos($string,'"credits": ')+11);
  2. $credits = substr($credits, 0, strpos($credits,','));


Do kolegów powyżej: gołym okiem widać, że to nie jest ani JSON, ani CSV, więc nie wiem, po co się wymądrzacie.
majesgrudziadz
Cytat(CuteOne @ 22.09.2012, 15:25:01 ) *
Skoro chcesz pomocy to wykonaj prostą rzecz, o którą prosiłem.


Tej prostej rzeczy ci nie dam gdyż wystarczy fragment kodu ja nie chce całego kodu a jedynie zapytania preg_match

Cytat(-Bebok- @ 22.09.2012, 15:52:16 ) *
  1. if( preg_match('/"credits": (\d+)/',$string,$match) ) {
  2. $credits = $match[1];
  3. }


Przy czym znacznie szybsze od regexpa na stringu o 50,000 znakach będzie coś takiego:

  1. $credits = substr($string, strpos($string,'"credits": ')+11);
  2. $credits = substr($credits, 0, strpos($credits,','));


Do kolegów powyżej: gołym okiem widać, że to nie jest ani JSON, ani CSV, więc nie wiem, po co się wymądrzacie.



dzękuję bardzo mi pomogłeś smile.gif

czy możesz wyjaśnić znaczenie +d questionmark.gif
-Bebok-
\d to po prostu cyfra; to samo co [0-9]
\d+ lub [0-9]+ to ciąg cyfr o długości co najmniej 1.
majesgrudziadz
hmm musze sie bardziej zagłębić w preg_match gdyż nigdzie nie moge znaleźć tego sensownie omówionego
-Bebok-
preg_match to tylko funkcja. To, w co chcesz się wgłębić, to używane przez nią wyrażenia regularne. Ściślej: PCRE, czyli wyrażenia regularne kompatybilne z Perlem (istnieje więcej sposobów zapisu wyrażeń regularnych, PHP korzysta z PCRE). Tu masz szybką ściągawkę: http://linuxdesigner.com/wp-content/upload...cheat_sheet.pdf a dogłębny opis oczywiście na stronach manuala PHP: http://www.php.net/manual/pl/reference.pcr...tern.syntax.php
majesgrudziadz
mimo wszystko nie moge sobie poradzic

daje zamiast d+ wstawiam w+ i nie wyciaga mi danych z takiego fragmentu


"playerName": "nick",

szukam "playerName": "

aby odczytac nazwe nick

mozesz mi pomoc ostatni raz smile.gif tego mi brak do szczescia

"playerName": "nazwagracza",
"mapDisplayName": "Nazwa Mapy",
"dateTime": "22.09.2012 00:01:32"

takie dane musze jescze wyciagnac ... jakby ktos mogl pomoc

UP

pomoże ktoś ?
redeemer
Możesz wkleić cały plik a przynajmniej jego początek?
majesgrudziadz
Początek pliku który wyciągam do string:

24 f {"mapName": "02_malinovka", "playerID": 502674822, "playerVehicle": "germany-Lowe", "gameplayType": "assault", "playerName": "mojnick", "vehicles":
......

"credits": 64921, "markOfMastery": 0, "gold": 0, "killed": [9047216], "tmenXP": 712, "hits": 11, "tkillRating": 0.0, "spotted": [9047217], "creditsPenalty": 0, "damageReceived": 1650, "tkillLog": [], "shots": 21, "lifeTime": 554, "creditsContributionOut": 0, "ammo": [16922, 19, 17178, 0, 17434, 0, 251, 1, 1275, 0, 763, 1], "arenaTypeID": 131074}, {"9047210": {"vehicleType": "ussr:IS", "isAlive": false, "name": "jaspion", "clanAbbrev": "", "team": 2, "events": {}, 2}, "9047219": {"frags": 1}, "9047220": {"frags": 1}, "9047221": {"frags": 0}, "9047222": {"frags": 1}, "9047223": {"frags": 1}, "9047224": {"frags": 3}, "9047225": {"frags": 1}, "9047226": {"frags": 0}, "9047227": {"frags": 1}, "9047228": {"frags": 0}, "9047229": {"frags": 0}, "9047230": {"frags": 0}, "9047231": {"frags": 0}, "9047232": {"frags": 0}, "9047233": {"frags": 0}, "9047234": {"frags": 0}, "9047235": {"frags": 0}, "9047236": {"frags": 2}, "9047237": {"frags": 0}, "9047238": {"frags": 4}, "9047239": {"frags": 0}}]

poniżej to zapiski całej bitwy:

jest tego sporo wiec dam fragment:
ÁJ - Ŕ6=ç}˜ľ+˝\@€l’ąfƧ˝…±í3bŘtr„IůÝaę˜ ćÍúwCĚĽ´Ť)Žť[Ňs˝ąI_[śo—B7p—ő{p


Wyciągam już potrzebne mi dane ale musze wyciągnać jeszcze wartości:


"playerName": "nazwagracza",
"mapDisplayName": "Nazwa Mapy",
"dateTime": "22.09.2012 00:01:32"

Z racji tego że kod jest długi i nie mogę dać całego pokaże jego część.


a wyciągnąć mam to
redeemer
Mi to wygląda na JSON z jakąś modyfikacją w postaci dodania '24 f' na początku (licznik pól?) i binarnym (?) zapisem bitwy. Cały plik możesz wkleić tutaj: http://pastebin.com
majesgrudziadz
Cytat(redeemer @ 24.09.2012, 15:13:14 ) *
Mi to wygląda na JSON z jakąś modyfikacją w postaci dodania '24 f' na początku (licznik pól?) i binarnym (?) zapisem bitwy. Cały plik możesz wkleić tutaj: http://pastebin.com


co to za różnica jaki to plik i jakiego formatu skoro ja chce wyciagnac konkretne dane ?

w poprzednich postach wychągam cyfry w ten sposób
  1. if( preg_match('/"credits": (\d+)/',$string,$match) ) {
  2. $credits = $match[1];


i działa elegancko

w tym przypadku chce wyciągnąć to co jest między " "
czyli jak mamy:

"playerName": "nazwagracza",
"mapDisplayName": "Nazwa Mapy",
"dateTime": "22.09.2012 00:01:32"

chcę wyciągnąć to co pogrubione.
czyli konkretnie to co jest po "playerName": " a przed ",

więc co to za różnica co to jest za plik ?

jak się zaczyna replay " AQÍ^ŽđÍjB%Ö+WOŐű±ŮPŁx7Jť¸ČWčůĎHŃŹ®ÔwµdâĎzÓŹŹO˝ŁE§ĺşŕË" to dalej nie podałem bo też nie chciało przejść

najwazniejszy jest poczatek

plik masz pod adresem http://pastebin.com/J3q5Up6w
redeemer
Różnica taka, że zamiast się bawić w jakieś wyrażenia regularne mógłbyś użyć funkcji parsującej json_decode. Jest tutaj parę oddzielnych obiektów/tablic JSON (przynajmniej dwa) + dodatkowo dane binarne na końcu pliku. Ciebie interesuje ten pierwszy obiekt, bo z niego chcesz wyciągnać dane. Zresztą za google: http://forum.worldoftanks.eu/index.php?/to...ay-file-format/ Tutaj jest opis formatu tego pliku. Dodatkowo ostatni post zawiera kod PHP który powinien wyciągać te 2 JSONy.
majesgrudziadz
ja ciebie rozume prblem w tym ze ty nie rozumiesz mnie.
nie chce wyciagac wszystkiego preg_match jest dla mnie wystarczajace gdyz nie chce info z calego pliku a jedynie te 3 zmienne co opisalem powyzej.

dlatego preg_match jest wystarczajace tylko ze nie wiem jak zadac pytanie w preg_match

mi chodzi tylko o pomoc w zapytaniu nie pytam sie jak kodowany jest plik itp
redeemer
Rozumiem co chcesz osiągnać i podałem Ci rozwiązanie na tacy. Ten kod z forum +
  1. ...
  2. $o = json_decode($block1);
  3. var_dump($o->playerName);
  4. var_dump($o->mapDisplayName);
  5. var_dump($o->dateTime);
Rozwiązuje sprawę.
majesgrudziadz
Cytat(redeemer @ 24.09.2012, 16:19:30 ) *
Rozumiem co chcesz osiągnać i podałem Ci rozwiązanie na tacy. Ten kod z forum +
  1. ...
  2. $o = json_decode($block1);
  3. var_dump($o->playerName);
  4. var_dump($o->mapDisplayName);
  5. var_dump($o->dateTime);
Rozwiązuje sprawę.




czyli cos takiego

  1. <?php
  2. $replay_file = file_get_contents($_FILES["file"]["tmp_name"]);
  3. $part1 = 'LSignature/' . 'LBlocks/' . 'LBlock1_length/';
  4. $part2 = 'LBlock2_length/';
  5. $file_info_part1 = unpack($part1, $replay_file);
  6. $file_info_part2 = unpack($part2, (substr($replay_file, 12 + $file_info_part1['Block1_length'], 4)));
  7.  
  8. $file_info = array_merge($file_info_part1, $file_info_part2);
  9. $block1 = substr($replay_file, 12, $file_info['Block1_length']);
  10. $block2 = substr($replay_file, 12 + $file_info['Block1_length'] + 4, $file_info['Block2_length']);
  11.  
  12. $o = json_decode($block1);
  13. var_dump($o->playerName);
  14. var_dump($o->mapDisplayName);
  15. var_dump($o->dateTime);
  16.  
  17. ?>
  18.  


sprawdze i obadam dla potomnych

A więc zrobiłem taki kod:

  1.  
  2. <?php
  3.  
  4. $pliko = 'plik_powtorki.wotreplay'; // nazwa pliku
  5.  
  6. $fpo = fopen("$pliko", "r"); // otwieram plik
  7. $replay_file = fread(fopen("$pliko", "r"), filesize("$pliko")); // czytam caly plik do zmiennej replay_file
  8. fclose("$pliko"); // zamykam plik
  9.  
  10. //kod z forum wot
  11. $part1 = 'LSignature/' . 'LBlocks/' . 'LBlock1_length/';
  12. $part2 = 'LBlock2_length/';
  13.  
  14. $file_info_part1 = unpack($part1, $replay_file);
  15.  
  16. $file_info_part2 = unpack($part2, (substr($replay_file, 12 + $file_info_part1['Block1_length'], 4)));
  17. $file_info = array_merge($file_info_part1, $file_info_part2);
  18.  
  19. $block1 = substr($replay_file, 12, $file_info['Block1_length']);
  20. $block2 = substr($replay_file, 12 + $file_info['Block1_length'] + 4, $file_info['Block2_length']);
  21.  
  22. $obj1 = json_decode($block1);
  23. $obj2 = json_decode($block2);
  24. //koniec kodu z wot
  25.  
  26. //wyswietlam dane
  27. echo 'Data bitwy: '.$obj1->{'dateTime'}.'<br />';
  28. echo 'Tryb bitwy: '.$obj1->{'gameplayType'}.'<br />';
  29. echo 'Mapa Wyświetlana: '.$obj1->{'mapDisplayName'}.'<br />';
  30. echo 'Mapa Nazwa: '.$obj1->{'mapName'}.'<br />';
  31. echo 'Nagrał: '.$obj1->{'playerName'}.'<br />';
  32. echo 'Wot ID: '.$obj1->{'playerID'}.'<br />';
  33. echo 'Pojazd: '.$obj1->{'playerVehicle'}.'<br />';
  34. echo'<br>';
  35. echo 'Gwiazdka: '.$obj1->{'dailyXPFactor10'}.'<br />';
  36. echo 'Gwiazka inna: '.$obj2->{'aogasFactor10'}.'<br />';
  37. echo 'Zarobek: '.$obj2->{'credits'}.'<br />';
  38. echo 'Otrzymanych trafień: '.$obj2->{'shotsReceived'}.'<br />';
  39. echo 'Strzałów: '.$obj2->{'shots'}.'<br />';
  40. echo 'Trafień w cel: '.$obj2->{'hits'}.'<br />';
  41. echo 'Zabito przeciwników: '.$obj2->{'markOfMastery'}.'<br />';
  42. echo 'Doświadczenie: '.$obj2->{'xp'}.'<br />';
  43. echo 'Wolne doświadczenie: '.$obj2->{'freeXP'}.'<br />';
  44. echo 'Pozostało życia: '.$obj2->{'health'}.'<br />';
  45. echo 'Otrzymane obrażenia: '.$obj2->{'damageReceived'}.'<br />';
  46. echo 'Okupacja bazy: '.$obj2->{'capturePoints'}.'<br />';
  47. echo 'Obrona bazy: '.$obj2->{'droppedCapturePoints'}.'<br />';
  48. echo 'Wygrana: '.$obj2->{'isWinner'}.'<br />';
  49.  
  50. ?>



O tyle o ile 1 blok json jest ładowany elegancko o tyle 2 już nie

gdzie popełniam błąd ?

  1. var_dump(json_decode($block2));


array(3) { [0]=> object(stdClass)#157 (43) { ["crewActivityFlags"]=> array(5) { [0]=> int(1) [1]=> int(1) [2]=> int(1) [3]=> int(1) [4]=> int(1) } ["repair"]=> int(3185) ["potentialDamageReceived"]=> int(2400) ["xpPenalty"]=> int(0) ["damageDealt"]=> int(2057) ["arenaCreateTime"]=> int(1345146595) ["killedTypeCompDescrs"]=> array(4) { [0]=> int(5377) [1]=> int(11265) [2]=> int(4385) [3]=> int(4353) } ["potentialDamageDealt"]=> int(2240) ["achieveIndices"]=> array(1) { [0]=> int(3) } ["shotsReceived"]=> int(9) ["xp"]=> int(1794) ["eventIndices"]=> array(0) { } ["bonusType"]=> int(1) ["droppedCapturePoints"]=> int(0) ["killerID"]=> int(0) ["creditsContributionIn"]=> int(0) ["damaged"]=> array(6) { [0]=> int(29255595) [1]=> int(29255597) [2]=> int(29255600) [3]=> int(29255580) [4]=> int(29255581) [5]=> int(29255583) } ["vehicleID"]=> int(29255574) ["factors"]=> object(stdClass)#158 (2) { ["aogasFactor10"]=> int(10) ["dailyXPFactor10"]=> int(10) } ["capturePoints"]=> int(1) ["heroVehicleIDs"]=> array(1) { [0]=> int(29255588) } ["epicAchievements"]=> array(0) { } ["health"]=> int(898) ["vehicleLockMode"]=> int(0) ["freeXP"]=> int(88) ["honorTitles"]=> array(10) { [0]=> int(150994944) [1]=> int(201326593) [2]=> int(201326593) [3]=> int(201326595) [4]=> int(234881025) [5]=> int(234881025) [6]=> int(234881027) [7]=> int(218103808) [8]=> int(218103809) [9]=> int(218103810) } ["isWinner"]=> int(1) ["credits"]=> int(101052) ["markOfMastery"]=> int(3) ["gold"]=> int(0) ["killed"]=> array(4) { [0]=> int(29255581) [1]=> int(29255580) [2]=> int(29255595) [3]=> int(29255600) } ["tmenXP"]=> int(1794) ["hits"]=> int(7) ["tkillRating"]=> float(0) ["spotted"]=> array(0) { } ["creditsPenalty"]=> int(0) ["damageReceived"]=> int(752) ["tkillLog"]=> array(0) { } ["shots"]=> int(11) ["lifeTime"]=> int(373) ["creditsContributionOut"]=> int(0) .............................
abort
1. var_dump lepiej (czytaj: wygodniej) oglądać wewnątrz <pre>
2. drugi blok jest ładowany, nawet w Twoim zrzucie można zobaczyć indeksy 'damageReceived' czy 'droppedCapturePoints', to których próbujesz odwołać się poprzez $obj2.

IMHO problem jest taki, że to co chcez odczytać, to nie jest bezpośrednio np. $obj2->{'capturePoints'}, tylko np. $obj2[2]->{'capturePoints'} lub coś w tym stylu, ale więcej Ci nie powiem, bo strasznie nie cierpię diagnozować takiego var_dumpa (patrz p.1)
majesgrudziadz
wlasnie probowalem $obj[2] ale nic :/ i 1 i 3 i 4 smile.gif ok obadam bo dumpa daje smile.gif

$obj2[0]->{'credits'};

Kurcze próbowałem i 1 i 2 i 3 smile.gif zapomiałęm że pierwszym array jest 0 smile.gif

jest ok:)

wszystko działa smile.gif
redeemer
@abort: Wynik var_dump się czyta zawsze bezpośrednio, ze "źródła strony" (chociaż ja preferuje CLI). To co wypluwa na wyjście skrypt (i nie ważne w jakim jest języku pisany), a co renderuje przeglądarka to dwie różne rzeczy. Żadne <pre> nie są niezbędne/potrzebne, bo stosowanie funkcji var_dump() jest zazwyczaj jednorazową operacja w celu zbadania obiektu/tablicy/zmiennej nie wspominając już nawet, że w stylach może być, dla przykładu, ustawione display:none na tag <pre> i w takim wypadku nic nie zobaczysz, chyba że zajrzysz do źródła strony smile.gif

Lekki offtop: raz musiałem zrobić reverse var_dump. To było ciekawe doświadczenie wink.gif
abort
Cytat(redeemer @ 25.09.2012, 00:51:52 ) *
@abort: Wynik var_dump się czyta zawsze bezpośrednio, ze "źródła strony" (chociaż ja preferuje CLI). To co wypluwa na wyjście skrypt (i nie ważne w jakim jest języku pisany), a co renderuje przeglądarka to dwie różne rzeczy. Żadne <pre> nie są niezbędne/potrzebne, bo stosowanie funkcji var_dump() jest zazwyczaj jednorazową operacja w celu zbadania obiektu/tablicy/zmiennej

Ja lubię mieć to wprost na stronie w postaci preformatowanej. Bo widzę zarówno debug tego co mnie interesuje, jak i całą stronę (a nie np. kod HTML całej strony w jednej linii, którą muszę przewijać w poziomie). A jeśli CHCĘ mieć <pre> widoczne, to na pewno nie ustawię mu "display:none", chyba że zgłupieję.
No ale ja dziwny jestem, i truskawki cukrem posypuję...
!*!
redeemer - chodzi tylko o ewentualne formatowanie tego co wypluje, po co czytać tablice ciurkiem, jak można jeden pod drugim. i dlatego w większości FW masz nakładki pr(). vd() które wstawiają wszytko w <pre>. Wygoda, lenistwo i ...

Cytat
No ale ja dziwny jestem, i truskawki cukrem posypuję...

prewer. stać Cie na cukier? burżuj.

Cytat( @ 25.09.2012, 00:51:52 ) *
Lekki offtop: raz musiałem zrobić reverse var_dump. To było ciekawe doświadczenie wink.gif

Jak offtop to offtop... tzn. co w tym ciekawego? są jakieś utrudnienia?
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.