Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

3 Stron V   1 2 3 >  
Reply to this topicStart new topic
> Usuwanie pustych atrybutów html, regex
Strelok
post 8.03.2018, 16:30:07
Post #1





Grupa: Zarejestrowani
Postów: 5
Pomógł: 0
Dołączył: 13.02.2018

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


Witam, problem wygląda następująco:

W poniższym kawałku HTML chciałbym złapać wszystkie puste atrybuty attr (oznaczone na czerwono):

<img src="/test-image_1.jpg" attr="test-image_1" qwe="asd" attr>
<img src="/test-image_1.jpg" attr="test-image_1" qwe="asd" attr=>
<img src="/test-image_1.jpg" attr= "test-image_1" qwe="asd" attr="">
<img src="/test-image_1.jpg" attr= "test-image_1" qwe="asd" attr=" ">
<img attr="a attr b" src="/test-imagalte_1.jpg" attr qwe="asd" />
<img src="/test- alt image_1.jpg" attr="test-image_1" attr= "" qwe="asd" >
<img src="/test-image_1.jpg" attr = " " asd=" q" attr="test-image_1" attr qwe="asd" >

Poprzez "puste" rozumiem także atrybuty attr zawierające między cudzysłowami białe znaki.
Dodatkowo ciągi attr występujące pomiędzy cudzysłowami nie powinny zostać złapane.

Wyrażenie które mam na ten moment:
/attr(?=(?:[^"]*"[^"]*")*[^"]*\Z)/gi

https://regex101.com/r/MvpdM9/1

Ten post edytował Strelok 8.03.2018, 16:32:25
Go to the top of the page
+Quote Post
SmokAnalog
post 9.03.2018, 00:28:48
Post #2





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Powiem Ci, że będzie ciężko. Wyrażenie regularne może mieć dużo pułapek i nie używałbym go do tego celu. Najlepiej to by było znaleźć bibliotekę do parsowania drzewa DOM, która potrafi znaleźć duplikaty atrybutów. Zduplikowany atrybut już nie jest prawidłowym HTML-em.

Chodzi o jednorazowe czyszczenie czy potrzebujesz skryptu, który będzie to robił wielokrotnie?
Go to the top of the page
+Quote Post
Pyton_000
post 9.03.2018, 08:42:47
Post #3





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Użyj sobie tego: https://github.com/paquettg/php-html-parser

Znajdź wsystkie `img` potem iteruj po nich sprawdzając

if(trim($item->getAttribute('attrib')) === '')

i zapisuj.

Ten post edytował Pyton_000 9.03.2018, 08:42:58
Go to the top of the page
+Quote Post
SmokAnalog
post 9.03.2018, 12:55:03
Post #4





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Pyton, ale jest jeden problem. Te biblioteki w zależności od implementacji wyłapują tylko pierwsze lub ostatnie wystąpienie danego atrybutu, bo prawidłowy HTML i ogólnie XML nie mogą mieć powtórzonych atrybutów. Dla obu przypadków, kiedy na przykład masz taki oto znacznik:

  1. <div attr="" attr="Misie koala" attr="">Pandy też</div>


Parser w ogóle nie dowie się, że w środku jest jakaś wartość, a raczej nie chodzi autorowi o to, żeby wyrzucać wszystkie w takim przypadku, tylko te puste.

Moim zdaniem w grę wchodzi szukanie biblioteki, która pozwoli na znalezienie wszystkich atrybutów o danej nazwie (wątpliwe czy taka biblioteka istnieje), a w ostateczności mała modyfikacja dowolnego parsera DOM. Tak, wiem - brzydko, ale co zrobić.

Od biedy można użyć parsera do wyłapania elementów (selektor CSS [attr]) i potem już zabawa z wyrażeniem regularnym. Nadal brudno, ale jednak mniejsza szansa na zepsucie całego HTML-a biggrin.gif

Ten post edytował SmokAnalog 9.03.2018, 12:56:43
Go to the top of the page
+Quote Post
Pyton_000
post 9.03.2018, 13:29:01
Post #5





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Nie doczytałem że tam może być więcej attr w tagu.

Masz rację. DOM w php odczytuje tylko pierwszy attr.

No to pozostaje zabawa regexp.
Go to the top of the page
+Quote Post
trzczy
post 9.03.2018, 14:01:25
Post #6





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Co w tym trudnego?

https://regex101.com/r/qZ7Slx/1

  1. \s?\battr\s*=\s*"\s*"|\s?\battr\b\s*=(?![^=<>]*")(?!\s*=)|\s?\battr\b(?![^=<>]*")(?!\s*=)
Go to the top of the page
+Quote Post
Pyton_000
post 9.03.2018, 14:14:43
Post #7





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Nic trudnego tylko nikomu się nie chciało takiego potworka pisać tongue.gif
Go to the top of the page
+Quote Post
Strelok
post 9.03.2018, 14:27:36
Post #8





Grupa: Zarejestrowani
Postów: 5
Pomógł: 0
Dołączył: 13.02.2018

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


Cytat(trzczy @ 9.03.2018, 14:01:25 ) *
Co w tym trudnego?

https://regex101.com/r/qZ7Slx/1

  1. \s?\battr\s*=\s*"\s*"|\s?\battr\b\s*=(?![^=<>]*")(?!\s*=)|\s?\battr\b(?![^=<>]*")(?!\s*=)

Dzięki, wygląda nieźle smile.gif Jeszcze tylko lekko zmodyfikować pod kątem łapania apostrofów i double quotes i powinno być w porządku. Istnieje jeszcze taki rzadki przypadek gdy nazwa tagu będzie się pokrywać z szukanym atrybutem, np. <attr attr="">.

Ja napisałem coś takiego (nieco moich wymagań spełnia smile.gif):

  1. attr(?:(?:\s*=\s*".*?"|\s*=\s*'.*?')|(?=(?:[^"']*["'][^"']*["'])*[^"']*\Z)[\s]*=?[\s]*?)


Hmm i jeszcze jeden przypadek kiedy "attr" jest fragmentem nazwy innego atrybutu z myślnikiem, np. <img attr="" attr-inny="">.

E:

powinienem jeszcze dodać, że danymi wejściowymi dla takiego regexa będzie właściwie tylko jeden tag html z zawartością, np.:
<img src="/test-image_1.jpg" attr= "test-image_1" qwe="asd" attr=" ">
albo
<attr src="/test-image_1.jpg" attr= "test-image_1" qwe="asd" attr=" ">
albo
<img src="/test-image_1.jpg" attr= "test-image_1" qwe="asd" attr-qwe=" ">

Ten post edytował Strelok 9.03.2018, 14:42:01
Go to the top of the page
+Quote Post
SmokAnalog
post 9.03.2018, 14:53:00
Post #9





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Cytat(trzczy @ 9.03.2018, 14:01:25 ) *
Co w tym trudnego?

https://regex101.com/r/qZ7Slx/1

  1. \s?\battr\s*=\s*"\s*"|\s?\battr\b\s*=(?![^=<>]*")(?!\s*=)|\s?\battr\b(?![^=<>]*")(?!\s*=)

Tak kozaczysz, a Twoje wyrażenie polega na zwykłym stringu:
  1. <div>attr</div>


Po prostu regexa się nie używa w takim celu i tyle, bo tworzy to niesamowicie nieczytelny i podatny na błędy kod (jak widać).
Go to the top of the page
+Quote Post
Pyton_000
post 9.03.2018, 15:04:43
Post #10





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Pytanie skąd taki śmietnik przychodzi...
Go to the top of the page
+Quote Post
trzczy
post 9.03.2018, 15:40:20
Post #11





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


@SmokAnalog taaa...
@Strelok, najlepiej zapodaj string do przetestowania regexu. Wtedy jest mniej pytań ze strony układającego regex.

Ten post edytował trzczy 9.03.2018, 15:43:03
Go to the top of the page
+Quote Post
Strelok
post 9.03.2018, 15:56:37
Post #12





Grupa: Zarejestrowani
Postów: 5
Pomógł: 0
Dołączył: 13.02.2018

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


Cytat(trzczy @ 9.03.2018, 15:40:20 ) *
@Strelok, najlepiej zapodaj string do przetestowania regexu. Wtedy jest mniej pytań ze strony układającego regex.

Dajmy na to tag o nazwie attr, gdzie szukane puste atrybuty to attr:
  1. <attr attr src="/test-image_1.jpg" attr = " " asd=" q" attr="test-image_1.jpg" attr qwe="as-d q-q" x="attr asd" >


Ten post edytował Strelok 9.03.2018, 15:56:58
Go to the top of the page
+Quote Post
trzczy
post 9.03.2018, 16:12:03
Post #13





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Wersja z <attr akceptowalnym:

https://regex101.com/r/qZ7Slx/3
Go to the top of the page
+Quote Post
SmokAnalog
post 9.03.2018, 21:55:31
Post #14





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Nadal wyłapujesz luźny ciąg znaków attr niebędący atrybutem, więc Twój kod jest bezużyteczny.
Go to the top of the page
+Quote Post
trzczy
post 9.03.2018, 22:10:36
Post #15





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Postawiłem sobie za zadanie spełniać testy. Bezużyteczność to twoje urojenia.
Go to the top of the page
+Quote Post
SmokAnalog
post 9.03.2018, 22:20:30
Post #16





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


No to dodaj prawidłowo te testy haha.gif Co to w ogóle jest za odpowiedź haha.gif
Go to the top of the page
+Quote Post
trzczy
post 9.03.2018, 22:25:02
Post #17





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Jeśli masz jakieś wymagania, to zapraszam do giełdy.
Go to the top of the page
+Quote Post
SmokAnalog
post 9.03.2018, 22:26:37
Post #18





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Nie no, super. Dodawaj złą odpowiedź bez uprzedzenia (bo nie przetestowałeś dokładnie) i chciej kasy za prawidłową. Twój kod ma podstawowy błąd, bo upierasz się jak zwykle przy wyrażeniach regularnych, mimo że nie masz w nich wprawy i nie wiesz kiedy należy ich unikać.
Go to the top of the page
+Quote Post
trzczy
post 9.03.2018, 22:29:09
Post #19





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Znajdź sobie więc fajniejszego kolegę. Ja oferuję regexy spełniające testy zadane przez pytającego.
Go to the top of the page
+Quote Post
SmokAnalog
post 9.03.2018, 22:34:10
Post #20





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

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


Mam nadzieję, że jeśli pracujesz z klientami to wkładasz trochę więcej serca w pracę. Klient (lub osoba pytająca) nie ma obowiązku umieć utworzyć testów i kolega wyżej po prostu przeoczył jeden z najważniejszych przypadków, kiedy ciąg znaków "attr" występuje w roli węzła tekstowego. Jak się odpowiada na pytania, trzeba myśleć za osobę pytającą, a nie rzucać odpowiedzią jak papuga.
Go to the top of the page
+Quote Post

3 Stron V   1 2 3 >
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: 19.04.2024 - 21:24