Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP]operacje na plikach
lamcpp
post
Post #1





Grupa: Zarejestrowani
Postów: 372
Pomógł: 2
Dołączył: 10.05.2009

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


mam plik *.txt, który wygląda mniej więcej tak:
2.0 1992.11 1975.10 22
1.1 1992.11 1975.10 35
1.1 SLE 1972.11 1975.10 40
&1300 MARATHON 1973.109 1975.08 42
...

Pytania:
-jak /przy pomocy jakiej funkcji dodać na początku każdego wiersza znak "$" (ale dodać tylko w tych wierszach, które nie mają znaku "&" na początku)
-jak usunąć wszystkie nadmiarowe spacje powyżej jednej
- za pomocą jakiej funkcji dodać przed ostatnimi numerami w rzędzie czyli przed 22, 35, 40, 42 znak ":", jak pomiędzy datami dodać znak "-"?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 13)
patryk9200
post
Post #2





Grupa: Zarejestrowani
Postów: 319
Pomógł: 4
Dołączył: 7.02.2009
Skąd: pless

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


poczytaj o wyrażeniach regularnych, wystarczy, że skopiujesz zawartość pliku do zmiennej, "przelecisz" całą kilkoma wyrażeniami regularnymi a potem wynik zapisać.
Go to the top of the page
+Quote Post
bastard13
post
Post #3





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

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



Wyrażenia regularne są rozwiązaniem twoich problemów:)
http://php.net/manual/en/book.pcre.php
Otwórz sobie plik z prawami do odczytu i zapisu. Przeleć pętlą po każdej linii, a tam wykonuj odpowiednie operacje:

Ad 1)
Sprawdź funkcją preg_match(), czy na początku linii jest znak &, jeżeli nie to dodaj $.
http://www.php.net/manual/en/function.preg-match.php

Ad 2)
http://www.php.net/manual/en/function.preg-replace.php

Ad 3)
Tutaj też preg_replace() z tym, że zabawa będzie ciekawsza:) Oprócz tego możesz zrobić exploda na linii po spacji i też zrobisz to, co chesz.
Go to the top of the page
+Quote Post
mortus
post
Post #4





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


@bastard13 Ale po co tak kombinować?
Wszystko można funkcjąi preg_replace() załatwić i to wywołując ją jeden raz:
  1. $sourceFileName = 'data.txt'; // tutaj zamiast data.txt wpisujesz nazwę swojego pliku
  2. $destinationFileName = 'data_'.time().'.txt'; // tutaj natomiast wpisujesz nazwę nowego pliku
  3. $content = file_get_contents($sourceFileName);
  4.  
  5. $patterns[0] = '#^[^&].*$#m';
  6. $patterns[1] = '#\s{2,}#';
  7. $patterns[2] = '#\s([0-9]+$)#m';
  8. $patterns[3] = '#([0-9]{4}.[0-9]{2})\s([0-9]{4}.[0-9]{2})#';
  9. $replacements[0] = '$$0';
  10. $replacements[1] = ' ';
  11. $replacements[2] = ':$1';
  12. $replacements[3] = '$1-$2';
  13.  
  14. $newContent = preg_replace($patterns, $replacements, $content);
  15. file_put_contents($destinationFileName, $newContent);

Dla przypadku 3 zamieniam spacje odpowiednio na : i -. Jeśli potrzebujesz tam również spacji, to dopisz je do $replacements[2] i $repecements[3].
Go to the top of the page
+Quote Post
bastard13
post
Post #5





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

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


@mortus
Ano rzeczywiście:)
Tylko to \s (dowolny biały znak) zamieniłby na \040 (spacja)

Ten post edytował bastard13 5.06.2011, 11:32:39
Go to the top of the page
+Quote Post
lamcpp
post
Post #6





Grupa: Zarejestrowani
Postów: 372
Pomógł: 2
Dołączył: 10.05.2009

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


A jak usunąć wszystkie puste linie z pliku?
Tzn. mam plik
pierwszy wpis

drugi wspi
trzeci wpis

czwarty wpis

I chciałbym te puste linie pomiędzy wpisami zlikwidować
Go to the top of the page
+Quote Post
erix
post
Post #7





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Alergia na wyszukiwarkę?

http://forum.php.pl/index.php?showtopic=45678
Go to the top of the page
+Quote Post
mortus
post
Post #8





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Można to również zrobić szybciej:
  1. $sourceFileName = 'data.txt';
  2. $content = file_get_contents($sourceFileName);
  3. $pattern = '#^[^\r\n].*$#m';
  4. preg_match_all($pattern, $content, $matches);
  5. $contentWithoutEmptyLines = implode($matches[0]);

Go to the top of the page
+Quote Post
erix
post
Post #9





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Ciekawe...

Ciekawe, czy posiadając plik o rozmiarze kilkuset MiB użyjesz tego samego.
Go to the top of the page
+Quote Post
lamcpp
post
Post #10





Grupa: Zarejestrowani
Postów: 372
Pomógł: 2
Dołączył: 10.05.2009

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


mając taki warunek:
$wzorzec[0]='#([0-9]{4}.[0-9]{2})\s([0-9]{4}.[0-9]{2})\s#';
$zamiana[0]='$1-$2:';

chciałbym dodać do niego by wzorzec nie odnosił się do elementów które rozpoczynają się od znaku $ i & (ale odnosił się do wszystkich pozostałych)
Jak to zrobić? Próbowałem tak zmieniając wzorzec:
$wzorzec[0]='[^&]*#([0-9]{4}.[0-9]{2})\s([0-9]{4}.[0-9]{2})\s#';
$zamiana[0]='$1-$2:';
ale to nie daje efektu.
Również problem mam z przedstawionym na forum:
$patterns[1] = '#\s{2,}#';
$replacements[1] = ' ';
który usuwa spacje. Tylko usuwa..zbyt dokładnie, tzn nie wiem dlaczego ale poza spacjami usuwa tez znak nowej linii, przez co wszystkie linie się "pozlepiały" ze sobą.
ps. dziękuję za dotychczasowe odpowiedzi
Go to the top of the page
+Quote Post
mortus
post
Post #11





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Cytat(erix @ 8.06.2011, 10:41:41 ) *
Ciekawe...

Ciekawe, czy posiadając plik o rozmiarze kilkuset MiB użyjesz tego samego.

Podejrzewam, że przy pliku o rozmiarze kilkudziesięciu MiB byłyby już problemy, a przetwarzanie plików o rozmiarze kilkuset MiB dla obu metod byłoby czasochłonne, choć z pewnością funkcja file() wygrałaby ewentualną rywalizację.
Osobiście przerzuciłbym dane do bazy danych.

Wracając do tematu:
  1. $wzorzec[0]='#^[^&|$].*([0-9]{4}.[0-9]{2})\040([0-9]{4}.[0-9]{2}).*$#m';
  2. $zamiana[0]='$1-$2:';

We wszystkich wzorcach zamień \s na \040, jak radził bastard13, a nie będzie problemów ze "zjedzonym" znakiem nowej linii.

Swoją drogą mój poprzedni kod nie działa do końca prawidłowo (jeszcze nie wiem dlaczego). Natomiast do usunięcia pustych linii możemy również wykorzystać funkcję preg_replace():
  1. $sourceFileName = 'data.txt';
  2. $content = file_get_contents($sourceFileName);
  3. $pattern = "#(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+#";
  4. $replacement = "\n";
  5. $contentWithoutEmptyLines = preg_replace($pattern, $replecement, $content);
Go to the top of the page
+Quote Post
lamcpp
post
Post #12





Grupa: Zarejestrowani
Postów: 372
Pomógł: 2
Dołączył: 10.05.2009

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


Chciałbym aby wyrażenie, które nie ma jako pierwszego znaku & otrzymało na początku linii znak ^ (a następne znaki żeby pozostały takie same
Czyli mam tekst:
&ACTdf hatchbed 1995.09 2000.09
1,6 1995.09 2000.09 66
2,6 1993.09 2001.09 62
I chciałbym by wyglądał on tak
&ACTdf hatchbed 1995.09 2000.09
^1,6 1995.09 2000.09 66
^2,6 1993.09 2001.09 62
Próbowałem już wielu sposobów żeby to zrobić np
$wzorzec[1]='#^[^&](.*)$#m';
$zamiana[1]='^$1';
ale to nie działa tak jak trzeba (ucina mi początek wyrazenia)

W pozostałych przykładach też nie działa to tak jak trzeba, zamiast negować cały ciąg, neguje mi pojedynczy znak;/
Go to the top of the page
+Quote Post
mortus
post
Post #13





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Cytat(lamcpp @ 8.06.2011, 21:50:23 ) *
Chciałbym aby wyrażenie, które nie ma jako pierwszego znaku & otrzymało na początku linii znak ^ (a następne znaki żeby pozostały takie same
Czyli mam tekst:
&ACTdf hatchbed 1995.09 2000.09
1,6 1995.09 2000.09 66
2,6 1993.09 2001.09 62
I chciałbym by wyglądał on tak
&ACTdf hatchbed 1995.09 2000.09
^1,6 1995.09 2000.09 66
^2,6 1993.09 2001.09 62
Próbowałem już wielu sposobów żeby to zrobić np
$wzorzec[1]='#^[^&](.*)$#m';
$zamiana[1]='^$1';
ale to nie działa tak jak trzeba (ucina mi początek wyrazenia)

W pozostałych przykładach też nie działa to tak jak trzeba, zamiast negować cały ciąg, neguje mi pojedynczy znak;/

Ale przecież wyżej masz podobne wyrażenie ($patterns[0], $replacements[0]). Czy tak ciężko jest zamienić znak $ na ^ w $replacements[0]?
Go to the top of the page
+Quote Post
lamcpp
post
Post #14





Grupa: Zarejestrowani
Postów: 372
Pomógł: 2
Dołączył: 10.05.2009

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


Teraz juz rozumiem:)
Jeszcze jedno pytanie (juz ostatnie) z ktorym nie mogę sobie poradzic:
otoz mam dwa rodzaje linijek tekstu(z pojedynczą datą w postaci 2000.02, oraz z dwoma datami w postaci 2000.02 2005.03).
Oto przykłady:
1) pojedyncza data:
&TRANS 1996.08
&MON 1976.04
2)podwójna data
&TRANS 1996.08 1999.05
&MON 1976.04 2003.05

Chciałbym aby zostały zmienione tylko te linijki, które zawierają pojedyńczą datę. Wpisuję więc kod:
  1. $wzorzec[4]='#&(.*)([0-9]{4})[,|.]([0-9]{2})#m';
  2. $zamiana[4]='&$1:$2.$3-';

Niestety kod działa również na linijki z podwójną datą, jak więc zapisać by działało tylko z pojedynczą datą?
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 22.08.2025 - 17:10