Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Wyrażenie regularne na liczby
DNMX
post 27.01.2023, 22:39:19
Post #1





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


Jakim wyrażeniem wydobędę z czegoś takiego:
Kod
Długość: 12,5 cm
Szerokość 20cm
Pojemność 0,7 L
Waga 1.5 kg

Liczby:
12,5
20
0,7
1,5
?
Go to the top of the page
+Quote Post
Salvation
post 27.01.2023, 23:40:25
Post #2





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

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


Kod
/\d+(?:(?:,|\.)\d+)?/guim


Ten post edytował Salvation 27.01.2023, 23:45:02
Go to the top of the page
+Quote Post
DNMX
post 30.01.2023, 10:02:00
Post #3





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


Ok a w czymś takim:
var_dump($data)
Kod
array(1) {
  ["items"]=>
  array(5) {
    [0]=>
    array(2) {
      ["label"]=>
      string(21) "Długość opakowania"
      ["value"]=>
      string(4) "1 cm"
    }
    [1]=>
    array(2) {
      ["label"]=>
      string(21) "Wysokość opakowania"
      ["value"]=>
      string(6) "2.3 cm"
    }
    [2]=>
    array(2) {
      ["label"]=>
      string(22) "Szerokość opakowania"
      ["value"]=>
      string(5) "20 cm"
    }
    [3]=>
    array(2) {
      ["label"]=>
      string(11) "Waga brutto"
      ["value"]=>
      string(8) "0.149 kg"
    }
    [4]=>
    array(2) {
      ["label"]=>
      string(25) "Liczba sztuk w opakowaniu"
      ["value"]=>
      string(4) "NULL"
    }
  }
}

  1. foreach($data['items'] as $item) {
  2. if(preg_match('/Szerokość/i', $item['label'])) {
  3. $Width = preg_match('/\d+(?:(?:,|\.)\d+)?/guim', $item['value'], $Width);
  4. echo "############" .$Width." #################";
  5. }
  6. }

Wyrzuca PHP Warning: preg_match(): Unknown modifier 'g' in i daje pustą wartość.
Kod
############ #################
Go to the top of the page
+Quote Post
trueblue
post 30.01.2023, 10:09:21
Post #4





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

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


preg_match nie przeszukuje globalnie, od tego jest preg_match_all
Sprawdź też trzeci parametr preg_match.


--------------------
Go to the top of the page
+Quote Post
DNMX
post 30.01.2023, 10:15:59
Post #5





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


Zauważyłem, 3-ci parametr niepotrzebyn. Usunąłem ale wciąż to samo.

Co to znaczy nie przeszukuje globalnie? Mam użyć teg preg_match_all? Sorry ale jestem początkujący jeśli chodzi o wyrażenia regularne. Szukam raczej gotowca z wyjaśnieniem.
Go to the top of the page
+Quote Post
trueblue
post 30.01.2023, 10:22:15
Post #6





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

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


Mógłbyś zajrzeć w dokumentację.
Dla preg_match_all jest wyjaśnienie:
Cytat
Searches subject for all matches to the regular expression given in pattern and puts them in matches...

Jeśli nie potrzebujesz wyszukiwać wszystkich liczb w stringu, lecz jeden, to wystarczy preg_match. A skoro preg_match nie przyjmuje parametru 'g', to znaczy, że ma go tam nie być.

Trzeci parametr funkcji jest porzebny, a wobec powyższego jego usuwanie nie jest rozwiązanie problemu.


--------------------
Go to the top of the page
+Quote Post
kreatiff
post 30.01.2023, 10:22:23
Post #7





Grupa: Zarejestrowani
Postów: 324
Pomógł: 105
Dołączył: 7.08.2012

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


Spróbuj tak pokombinować (chodzi o wyciąganie tych danych z tablicy):
  1. $x = array_map(fn($i) => preg_replace('#[^0-9\,\.]#', '', $i), array_column($data, 'value'));


Ten post edytował kreatiff 30.01.2023, 10:23:09
Go to the top of the page
+Quote Post
DNMX
post 30.01.2023, 11:05:08
Post #8





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


Z preg_replace zadziałało. Dzięki!
Go to the top of the page
+Quote Post
trueblue
post 30.01.2023, 11:27:31
Post #9





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

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


Jeśli oprócz wartości pojawi się cyfra w innym miejscu, np. w jednostce (cm2), to wynik będzie błędny.


--------------------
Go to the top of the page
+Quote Post
kreatiff
post 30.01.2023, 12:02:55
Post #10





Grupa: Zarejestrowani
Postów: 324
Pomógł: 105
Dołączył: 7.08.2012

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


Słuszna uwaga od trueblue.
Jeśli taka sytuacja zachodzi, to trzeba będzie doprecyzować wyrażenie, by np. wycinało wszystko co jest po pierwszej spacji lub literze. Zależy jakie wartości mogą pojawić się w 'value'.
Go to the top of the page
+Quote Post
DNMX
post 1.02.2023, 12:06:32
Post #11





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


Jeszcze jedno pytanie w temacie. Zanim wyjdzie mi taka ładna tablica jak w drugim poscie, wykonuję json_decode() na $raw_json który jest stringiem:
Kod
string(314) "{"items":[{"label":"Długość opakowania","value":"1.5 cm"},{"label":"Wysokość opakowania","value":"16 cm"},{"label":"Szerokość opakowania","value":"4.5 cm"},{"label":"Waga brutto","value":"0.08 kg"},{"label":"Wymiary produktu","value":"szer. ostrza 18 mm"},{"label":"Liczba sztuk w opakowaniu","value":"10"}]"

W przypadku powyżej wszystko jest OK ale w takim przypadku:
Kod
string(254) "{"items":[{"label":"Długość opakowania","value":bi},{"label":"Wysokość opakowania","value":"3.75 cm"},{"label":"Szerokość opakowania","value":bi},{"label":"Waga brutto","value":"0.891 kg"},{"label":"Wymiary produktu","value":"3,7 x 3,5 x 3,5 cm"}]"

funkcja json_decode() zwraca pustą tablicę (NULL). Domniemuję, że to dlatego, iż niektóre wartości przyjmują wartość innej zmiennnej, jak np. bi albo bk, bd itp. Zastanawiam się, jak to ominąć. Jedyne co przychodzi mi do głowy to wyrażenie regularne które zamieni
Kod
"value":bi}
"value":bk}
"value":bd}

na
Kod
"value":"0.00"}

Innymi słowy, wartości, które nie są wyescapowane (zaczynają i kończą się na ") zamienić na "0.00". Da się na to stworzyć jakieś wyrażenie regularne?
Go to the top of the page
+Quote Post
Salvation
post 1.02.2023, 13:22:29
Post #12





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

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


Pomijając problem niezamkniętej klamry na końcu, to jeżeli te `bi`, `bk` i `bd`, to stałe, to możesz użyć takiego kodu:
  1. preg_replace('/\:b(?:i|d|k)}/ui', ':"0.00"}', $jsonString);
Go to the top of the page
+Quote Post
DNMX
post 1.02.2023, 13:49:22
Post #13





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


To tylko przykłady nazw stałych. Jest ich mnóśtwo wiecej niż bi, bk i bd. Nazwy różnej długości. Dlatego też chciałem łapać wszystko, co nie ma klamry.
Go to the top of the page
+Quote Post
trueblue
post 1.02.2023, 14:20:42
Post #14





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

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


Dodając cudzysłowy do bk, bi, itd., wynik parsowania jest poprawny.


Takiego stringa: 3,7 x 3,5 x 3,5 cm nie przetworzysz na wartość liczbową przy pomocy preg_replace.


--------------------
Go to the top of the page
+Quote Post
DNMX
post 1.02.2023, 22:11:32
Post #15





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


Wiem o tym dlatego szukam regexpa, który zamieni "value":bi} na "value":"bi"}, "value":bk} na "value":"bk"} itd, itp. Ogólnie mówiąc, to co występuje po "value", a } i doda do tego " "
Go to the top of the page
+Quote Post
Salvation
post 2.02.2023, 00:07:04
Post #16





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

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


No dobra, to takie coś:
  1. preg_replace('/"value":([a-z]+)}/ui', '"value":"${1}"}', $jsonString);

Demo: https://3v4l.org/7QBET
Go to the top of the page
+Quote Post
DNMX
post 2.02.2023, 07:07:32
Post #17





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


O dzięki, właśnie o coś takiego chodziło! Zadziałało, w sensie zmienia wartość value na "value" ale cały skrypt wypluwa jeszcze errory. Zauważyłem, że są też labele bez "":
Kod
string(331) "{"items":[{"label":[b]bx[/b],"value":"by"},{"label":"Grubość produktu","value":"18 mm"},{"label":"Wysokość produktu","value":"71,5 cm"},{"label":"Waga brutto","value":"4.86 kg"},{"label":"Szerokość opakowania","value":"80.5 cm"},{"label":"Wysokość opakowania","value":"2.3 cm"},{"label":"Długość opakowania","value":"50.3 cm"}]"
NULL

Zmodyfikowałem analogicznie kod:
  1. $data = preg_replace('/"label":([a-z]+)}/ui', '"label":"${1}"}', $data);

ale wypluwa to samo co u góry. Co jeszcze robię nie tak?
Go to the top of the page
+Quote Post
viking
post 2.02.2023, 07:57:26
Post #18





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Trochę nie rozumiem co ty robisz. Json jest albo poprawny, albo nie i wtedy jego poprawianie nie ma sensu. Teraz poprawisz 10 rzeczy a zaraz będzie kolejna zła. Zabawa bez sensu.


--------------------
Go to the top of the page
+Quote Post
DNMX
post 2.02.2023, 08:02:12
Post #19





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 18.09.2021

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


Radzę sobię, jak mogę. To nie jest JSON tylko fragment skryptu wycięty ze źródła strony. Takie dane niestety dostaję
Go to the top of the page
+Quote Post
Salvation
post 2.02.2023, 09:43:24
Post #20





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

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


Spróbuj takie coś. Koniecznie w tej kolejności:
  1. $jsonString = preg_replace('/":\[\w\]([a-z]+)\[\/\w\]/ui', '":${1}', $jsonString);
  2. $jsonString = preg_replace('/":([a-z]+)(,|})/ui', '":"${1}"${2}', $jsonString);

Demo: https://3v4l.org/CPlf9
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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: 27.04.2024 - 23:31