Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Wycinianie zawartości z ciągu znaków/usuwanie znaków z ciągu
Forum PHP.pl > Forum > Przedszkole
Star
Chcę przeparsować taki kod:

  1. <tr>
  2. <td class="class01"><a id="id01" href="http://jakislink.pl">BB</a> <a id="id01" href="http://jakislink.pl">AA</a></td>
  3. <td class="class02">YYY</td>
  4. <td class="class03">XXX</td>
  5. </tr>
  6.  
  7. <tr>
  8. <td class="class01"><a id="id01" href="http://jakislink.pl">YY</a>
  9. <td class="class02">YYY</td>
  10. <td class="class03">XXX</td>
  11. </tr>


jak widac, w pierwszym TR sa dwa odnosniki,a w drugim tylko jeden.
bez problemu wycinam pozostałe czesci ,tylko nie umiem ustawic tak,aby wykryło czy są dwa linki i jesli tak to ustawic w pętli np
BB AA
a jesli jeden to samo:
YY

Da rade cos takiego zrobic ?

i druga sprawa, mam tablce z imionami i nazwiskami i chciałbym usunąć z niej imiona. Mozna dodac jakas funkcje w ktorej zapiszemy imiona ktore mają zostac usunięte tak aby zostały same nazwiska?
SwiezuPL
Średnio rozumiem pytanie, ale postaram się pomóc.
Jeśli chodzi o pierwszą cześć pytania, poczytaj:
http://php.net/manual/en/function.empty.php
http://php.net/manual/en/function.isset.php
Co do imion i nazwisk;
http://www.php.pl/Wortal/Artykuly/Pomysly-...mocy-checkdnsrr
Poczytaj i zobacz jak wyciągnąć domenę z maila. Pomyśl i wykorzystaj to do oddzielenia imienia i nazwiska wink.gif
kreatiff
Da radę oraz można dodać jakąś funkcję.

Co do pierwszego mozna pokombinowac z tym preg_match_all tak jak w poprzednim wątku, np.:
  1. preg_match_all('#<a.*?>(.*?)</a>#', $a, $w);
Ale w tym wypadku tracisz ułożenie linków względem siebie (nie wiesz czy AA i BB były obok siebie, czy np. BB stał obok YY). Można to rozwiązać np. jakims bardziej skomplikowanym wzorem, albo najpierw wyciągnięciem komórek tabeli, które zawierają linki, a potem dla każdej takiej komórki wyciągnięcie tekstów linka.

Co do drugiego to wiele zależy od budowy tablicy. Gdy jest ona prosta, każdy element to albo imię albo nazwisko to wystarczy zwykłe array_diff z tablicą z imionami. Gdy elementy tablicy to "imię nazwisko", to wówczas pętla przez każdy element tablicy i podmiana imion na puste ciągi oraz trim dla wyniku, by usunąć zbędne białe znaki.
Star
Nie znam niestety tak dobrze się na tablicach i tym wycinaniu, mógłbyś pokazać jak to ma wyglądać?
kreatiff
Wklej kawałek tablicy z tymi imionami i nazwiskami, by wiedzieć od czego zacząć.
Star
  1. (
  2. [0] => Array
  3. (
  4. [0] => Łukasz Pilarczyk
  5. [1] => Dawid Brodawka
  6. [2] => Michał Łukowski
  7. )
  8. )


mam nadzieję ze cos wymyslisz bo ja nie mam pojęcia jak to wyciąć
kreatiff
Wyczyść dokładnie tak jak pisałem wink.gif
  1. $a = Array(
  2. 0 => Array
  3. (
  4. 0 => 'Łukasz Pilarczyk',
  5. 1 => 'Dawid Brodawka',
  6. 2 => 'Michał Łukowski'
  7. )
  8. );
  9.  
  10. $imiona = array('Łukasz', 'Dawid', 'Michał');
  11.  
  12. foreach ( $a[0] as &$wyczysc ) {
  13. $wyczysc = trim(str_replace($imiona, '', $wyczysc));
  14. }
  15. unset($wyczysc);
  16. echo'<pre>',var_dump($a),'</pre>';


Edycja:
jeśli jesteś pewien, że w tablicy zawsze znajduje się na przodzie imię, to nawet nie musisz tworzyć dodatkowej tablicy z imionami, a wystarczy wyciąć z $wyczysc w pętli tylko to co znajduje się po spacji, albo explode po spacji i array_pop, gdy może być wiecej imion, itp. kombinacje.
Star
musiałem lekko podmienic bo ja je wyciagam z pewnej strony,kod:
  1. preg_match_all('[<a id="login" href="http://jakislink.pl">(.+?)<\/a>]', $get, $getinfo);
  2. $a= $getinfo[2];
  3.  
  4. $imiona = array('Łukasz', 'Dawid', 'Michał');
  5.  
  6. foreach ( $a[0] as &$wyczysc ) {
  7. $wyczysc = trim(str_replace($imiona, '', $wyczysc));
  8. }
  9. unset($wyczysc);
  10. echo'<pre>',var_dump($a),'</pre>';


i wyswietla NULL. Co tutaj zle zrobiłem ?
kreatiff
Strzelam, bo nie znam wygląda zmiennej $getinfo. Jak już przypisujesz jej podtablicę do zmiennej $a, to w foreach nie używasz już odwołania do poddablicy ($a[0]), tylko po prostu $a.
Albo bez tworzenia dodatkowej zmiennej $a, po prostu robisz foreach dla $getinfo[2].
Star
Zadziałało jestes WIELKI exclamation.gif!!! smile.gif Męczyłem się z tym od kilku godzin, serdercze dzieki !:)

a dałbyś radę mi jeszcze pomóc z tym :

  1. Chcę przeparsować taki kod:
  2.  
  3. [php] <tr>
  4. <td class="class01"><a id="id01" href="http://jakislink.pl">BB</a> <a id="id01" href="http://jakislink.pl">AA</a></td>
  5. <td class="class02">YYY</td>
  6. <td class="class03">XXX</td>
  7. </tr>
  8.  
  9. <tr>
  10. <td class="class01"><a id="id01" href="http://jakislink.pl">YY</a>
  11. <td class="class02">YYY</td>
  12. <td class="class03">XXX</td>
  13. </tr>




jak widac, w pierwszym TR sa dwa odnosniki,a w drugim tylko jeden.
bez problemu wycinam pozostałe czesci ,tylko nie umiem ustawic tak,aby wykryło czy są dwa linki i jesli tak to ustawic w pętli np
BB AA
a jesli jeden to samo:
YY
[/php]

też nie mam pojęcia jak wyciągnąc dane z każdego TR

edit
zle napisałem
nie mam pojęcia jak oczytać czy są w TR dwa odnośniki czy jeden
kreatiff
Np. tym wyłapiesz wszystkie komórki, które mają linki:
  1. preg_match_all('#<td.*?>(?:<a.*?>)</td>#', $a, $w);
Następnie dla każdego wyniku łapania $w[1] możesz wyciągać treść linka taką samą regułą jak w poście 3, albo np. korzystając z funkcji strip_tags.

Jeszcze jedna ważna uwaga. HTML nie jest językiem regularnym, dlatego trzeba uważać stosując do jego parsowania wyrażenia regularne, bo można się wpędzić w maliny.
Zobrazować to co właśnie napisałem można na przykładzie kodu, który wkleiłeś w ostatnim poście. Zauważ, że w linii 10 brakuje domknięcia tagu komórki. Każda przeglądarka sobie w tym poradzi i skoryguje błąd. Wyrażenie regularne oparte na wzorze, gdzie ten tag jest zamknięty już tej konkretnej komórki nie wyłapie bazując na wzorze, który zapisałem.
Star
Wrzuciłem
  1. preg_match_all('#<td.*?>(?:<a.*?>)</td>#', $get, $w);
  2. print_r($w);

i pokazało pustą tablicę Array ( [0] => Array ( ) )

W źródle strony która parsuje jest wiele TR,tak jak tu podałem
  1. <tr>
  2. <td class="class01"><a id="id01" href="http://jakislink.pl">BB</a> <a id="id01" href="http://jakislink.pl">AA</a></td>
  3. <td class="class02">YYY</td>
  4. <td class="class03">XXX</td>
  5. </tr>
  6.  
  7. <tr>
  8. <td class="class01"><a id="id01" href="http://jakislink.pl">YY</a>
  9. <td class="class02">YYY</td>
  10. <td class="class03">XXX</td>
  11. </tr>


tutaj dałem dwa ,ale moze byc i 200, ja chcę zapisać do bazy każda wartość tej klasy z każdego TR osobno
gdy użyłem
  1. preg_match_all('[<a id="login" href="jakislink.pl/(.+?)">(.+?)<\/a>]', $get, $get2);


to niby wyszukało,ale problem się zrobił taki,że gdy wyswietliłem wszystko razem,tzn wartość z pierwszego odnosnika i z drugiego obok siebie to zlały mi się jesli w którymś TR tego drugiego odnośnika nie było i w efekcie przy nazwie pierwszego odnosnika była zła nazwa drugiego. Mam nadzieję ,że z tym tez cos wymyślisz, bo mnie nic do głowy nie przychodzi smile.gif
kreatiff
Działa, ale sprawa jest śliska:
  1. preg_match_all('#<td.*?>((?:<a).*)#', $a, $w);
  2. $w = $w[1];
  3. foreach ( $w as &$wyczysc ) {
  4. $wyczysc = strip_tags($wyczysc);
  5. }
  6. unset($wyczysc);
  7. echo'<pre>',var_dump($w),'</pre>';
salfunglandyare
Może coś podobnego? Nie testowałem, więc może być babol smile.gif
  1. $linki = array();
  2. preg_match_all('|<tr.*?>(.+?)</tr>|is',$get,$m,PREG_SET_ORDER);
  3. foreach($m as $tr){
  4. preg_match_all('|<a.*?href="http://jakislink\.pl(.*?)".*?>(.+?)</a>|is',$tr[1],$w,PREG_SET_ORDER);
  5. foreach($w as $a){
  6. $linki[] = array('link' => $a[1], 'nazwa' => $a[2]);
  7. }
  8. }
  9. print_r($linki);

Star
wrzucając kod od Ciebie Kreatiff mam cos takiego:
array(0) {
}

a od Salfunglandyare jest samo Array ( )

w kodzie pierwszym kodzie nie ma nic o TR a to własnie wazne aby wyciągnąć dane spod niego, bo gdy wrzucam samo TD to jesli nie ma drugiego odnosnika to pierwszemu dopisuje wartość nastepnego drugiego i to jest całym problemem

kreatiff
Trudno powiedzieć co nie pasuje. Mój kod podstawiajac mu pod $a dokłądnie to co w pierwszym pościa zwraca mi taką tablicę:
  1. array(2) {
  2. [0]=>
  3. string(6) "BB AA
  4. "
  5. [1]=>
  6. string(3) "YY
  7. "
  8. }
Czyli dokładnie tak jak zrozumiałem chcesz by zwracał. Więc możliwe, że zachodzą jakieś nieregularności w całym kodzie do sparsowania. To jest właśnie ta "śliskość" regexów parsujących html. Nie bardzo wiem jak dalej próbować idąc tą drogą.

Możesz też podejść całkiem inaczej. Rozbić całe źródło za pomocą explode po np. tagu otwierającym rząd tabeli <tr> i z kolejnych elementów tablicy powstałej po takim rozbiciu wyciągać treść linków, jeśli te istnieją.
Tym sposobem każdy element tablicy będzie miał tylko te linki, które znajdują się w danym rzędzie tabeli i można będzie je łątwo skleić w jedną całość.
salfunglandyare
Przetestowałem, mój działa, gdzie: $get - tu znajduje się html, domena to http://jakislink.pl
cały kod z testowania:
  1. $get = ' <tr>
  2. <td class="class01"><a id="id01" href="http://jakislink.pl/abc">BB</a> <a id="id01" href="http://jakislink.pl/costam=1&jeszcze=cos">AA</a></td>
  3. <td class="class02">YYY</td>
  4. <td class="class03">XXX</td>
  5. </tr>
  6.  
  7. <tr>
  8. <td class="class01"><a id="id01" href="http://jakislink.pl">YY</a>
  9. <td class="class02">YYY</td>
  10. <td class="class03">XXX</td>
  11. </tr>';
  12.  
  13. $linki = array();
  14. preg_match_all('|<tr.*?>(.+?)</tr>|is',$get,$m,PREG_SET_ORDER);
  15. foreach($m as $tr){
  16. preg_match_all('|<a.*?href="http://jakislink\.pl(.*?)".*?>(.+?)</a>|is',$tr[1],$w,PREG_SET_ORDER);
  17. foreach($w as $a){
  18. $linki[] = array('link' => $a[1], 'nazwa' => $a[2]);
  19. }
  20. }
  21. print_r($linki);
Star
Kreatiff, gdy dałemm tak kod :
  1. $natr = explode("<tr>", $d100);;
  2.  
  3. for ($i = 0; $i <= 100; $i++)
  4. { echo "$natr[$i] <br>";}

to mi sie cała strona załadowała,łacznie z tym co jest poza tr czyli <html> itp
Salfunglandyare ,własnie o to prawie chodzi tylko w jednej linii maja byc nazwy odnosników ,a w petli od Ciebie są nazwy i to co jest poza linkiem
czyli z takiego kodu
  1. <td class="class01"><a id="id01" href="http://jakislink.pl/abc">BB</a> <a id="id01" href="http://jakislink.pl/costam=1&jeszcze=cos">AA</a></td>

ma wyjść
BB AA

a z takiego
  1. <td class="class01"><a id="id01" href="http://jakislink.pl">YY</a></td>

ma wyjsc tylko
YY

da rade jakos to naprawic ?
salfunglandyare
  1. $linki = array();
  2. preg_match_all('|<tr.*?>(.+?)</tr>|is',$get,$m,PREG_SET_ORDER);
  3. foreach($m as $tr){
  4. preg_match_all('|<a.*?href="http://jakislink\.pl(.*?)".*?>(.+?)</a>|is',$tr[1],$w,PREG_SET_ORDER);
  5. $tmp = array();
  6. foreach($w as $a){
  7. $tmp[] = $a[2];
  8. }
  9. if(!empty($tmp)){
  10. $linki[] = $tmp;
  11. }
  12. }
  13. print_r($linki);


później:
  1. foreach($linki as $link){
  2. echo implode(' ',$link).'<br>';
  3. }
Star
Własnie o to chodzi ,tylko gdy podmieniam ta $get na zrodlo strony ktore trzeba przeparsowac to dalej wyskakuje tylko Array ( ) i nic poza tym sad.gif
salfunglandyare
a podmieniasz tez http://jakislink\.pl? jeśli Cię nie interesuje link, wtedy linie 4 zmien na:
  1. preg_match_all('|<a.*?>(.+?)</a>|is',$tr[1],$w,PREG_SET_ORDER);
salfunglandyare
No tak działa:
  1. $linki = array();
  2. preg_match_all('|<tr.*?>(.+?)</tr>|is',$get,$m,PREG_SET_ORDER);
  3. foreach($m as $tr){
  4. preg_match_all('|<a.*?>(.+?)</a>|is',$tr[1],$w,PREG_SET_ORDER);
  5. $tmp = array();
  6. foreach($w as $a){
  7. $tmp[] = $a[1];
  8. }
  9. if(!empty($tmp)){
  10. $linki[] = $tmp;
  11. }
  12. }
  13. //print_r($linki);
  14. foreach($linki as $link){
  15. echo implode(' ',$link).'<br>';
  16. }
Star
No pięknie, o to własnie chodziło ! :-)

a dało by rade to rozdzielic na dwa inputy ?
np
<input type=\"text\" name=\"nick\" value=\"$nick\" />
<input type=\"text\" name=\"klan\" value=\"$klan\" />

jak mozna zadeklarowac te dwie zmienne ? smile.gif

i czy szło by do tego dodac fukcje usuwająca ustawione wczesniej znaki ktora pokazał Kreatiff ?

$imiona = array('Łukasz', 'Dawid', 'Michał');

foreach ( $a as &$wyczysc ) {
$wyczysc = trim(str_replace($imiona, '', $wyczysc));
}
unset($wyczysc);
for ($i = 0; $i <= 101; $i++) {
echo"$a[$i] <br>";
}
salfunglandyare
Hmm smile.gif
  1. foreach($linki as $link){
  2. echo '<input type="text" name="nick" value="'.htmlspecialchars($link[0]).'" />';
  3. if(coung($link)>1){
  4. echo '<input type="text" name="klan" value="'.htmlspecialchars($link[1]).'" />';
  5. }
  6. echo '<br>';
  7. }

A co do usuwania znaków - jakie znaki chcesz usunąć?
Star
kod od Ciebie wyrzucił mi cos takiego w zrodle:
  1.  
  2. <input type="text" name="nick" value="&lt;/a&gt;
  3. &lt;/div&gt;
  4. &lt;/th&gt;
  5. &lt;th scope=&quot;col&quot;&gt;
  6. &lt;div id=&quot;tooltipLoot&quot; class=&quot;toolTip&quot;&gt;
  7. &lt;a class=&quot;thIcon iconBooty&quot; onclick=&quot;document.sorting.sort.value='loot'; document.sorting.submit();&quot;&gt;" />

na stronie pojawiło sie jedno pole tekstowe a w nim </a>

chciałbym aby była tablica ,tak jak np ta:
$imiona = array('Łukasz', 'Dawid', 'Michał');

i kazdy w kazdym nicku ktory ma w sobie np Michał zostanie to Michał usuniete, np z Michal Duzy zostanie samo Duzy
salfunglandyare
Bo wpisałem coung zamiast count tongue.gif zobacz to:
  1. $linki = array();
  2. preg_match_all('|<tr.*?>(.+?)</tr>|is', $get, $m, PREG_SET_ORDER);
  3. foreach ($m as $tr) {
  4. preg_match_all('|<a.*?>(.+?)</a>|is', $tr[1], $w, PREG_SET_ORDER);
  5. $tmp = array();
  6. foreach ($w as $a) {
  7. $tmp[] = $a[1];
  8. }
  9. if (!empty($tmp)) {
  10. $linki[] = $tmp;
  11. }
  12. }
  13. $linki = array_map(function($a) {
  14. $do_usuniecia = array('Łukasz', 'Dawid', 'Michał');
  15. $a[0] = trim(str_replace($do_usuniecia, '', $a[0]));
  16. return $a;
  17. }, $linki);
  18. //print_r($linki);
  19. foreach ($linki as $link) {
  20. echo '<input type="text" name="nick" value="' . htmlspecialchars($link[0]) . '" />';
  21. if (count($link) > 1) {
  22. echo '<input type="text" name="klan" value="' . htmlspecialchars($link[1]) . '" />';
  23. }
  24. echo '<br>';
  25. }
Star
Teraz przeszło smile.gif
tylko nadal w zródle mam cos takiego:
  1.  
  2. <input type="text" name="nick" value="&lt;/a&gt;
  3. &lt;/div&gt;
  4. &lt;/th&gt;
  5. &lt;th scope=&quot;col&quot;&gt;
  6. &lt;div id=&quot;tooltipLoot&quot; class=&quot;toolTip&quot;&gt;
  7. &lt;a class=&quot;thIcon iconBooty&quot; onclick=&quot;document.sorting.sort.value='loot'; document.sorting.submit();&quot;&gt;" />
tak powinno być ?

Usuwanie znaków tez działa,super smile.gif

salfunglandyare
Raczej nie - na podstawie tego html, który wkleiłeś nic takiego nie dostałem...
Star
Moja pomyłka, wszystko gra. Jeszcze raz serdeczne dzięki za pomoc smile.gif
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.