Jak parsować kody ascii z ciągu znaków?

0

Witam serdecznie kolegów i koleżanki,

wiem robię źle i na tym kończą się pomysły. Uparłem się, że to musi być w pythonie. Problem jest taki, mam string w którym są same cyfry, i ten string trzeba zamienić na kody ascii oddzielone przecinkiem.
Program testowy postarałem się żeby był przejrzysty:

import re

input_string = "000123259300269299255000"
numbers = [int(match) for match in re.findall(r'([3-9]\d{1}|[1-9]\d{2}|0)', input_string) ]

result = ','.join(map(str, numbers))

print(result)

W rezultacie wykonania programu otrzymuje: 0,0,0,123,259,30,0,269,299,255,0,0,0
Jak widać pierwsze trzy zera prawidłowo rozpoznane, 123 również jednak kolejne 259 jest błędne prawidłowo powinno być 25 a później 93 bo każdy wynik cząstkowy nie może być większy niż 255. Prawidłowy wynik parsowania ascii powinien wyglądać tak: 0,0,0,123,25,93,0,0,26,92,99,255,0,0,0.
Z góry dziękuje (thanks from mountain) za każdą podpowiedz jak to prosto wygenerować.
Pozdrawiam serdecznie...

5

Zajrzałem do książki Regular Expressions Cookbook, który podał mi że regex dla zakresu 0-255 to (25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]).

>>> re.findall("(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])", "000123259300269299255000")
['0', '0', '0', '123', '25', '93', '0', '0', '26', '92', '99', '255', '0', '0', '0']
1

Witam ponownie, dziś pytanie dziś odpowiedz, dziękuje bardzo, nie wymyśliłem takiego układu regex, 3 dni straciłem ale jest! Teraz wszystko śmiga bez trzymanki. Jak to mówią after birds!

3

@Spearhead już Ci dał rybę, ale gdybyś chciał wędkę, to gdybyś chciał do tego podejść inkrementacyjnie, to można tak:

  • wiemy że chcemy złapać pojedyncze cyfry, więc zaczynamy od [0-9]
  • wiemy że chcemy złapać też podwójne cyfry, więc można zrobić [0-9]{1,2}
    • tylko wtedy złapiemy też 00 jako pojedynczą liczbę. więc pierwszy znak nie może być zerem: [1-9]?[0-9]
  • chcemy złapać też liczby trzycyfrowe, ale nie wszystkie, tylko takie które zaczynają się od 1 i 2 (ale z tymi 2 to jeszcze za chwilę): dopisujemy opcjonalnie: 1? - 1?[1-9][0-9]
    • ale to nie łapie nam 100 (bo wcześniej napisaliśmy żeby nie łapało 00), przerabiamy na: 1[0-9]{2} albo [1-9]?[0-9]: czyli 1[0-9]{2}|[1-9]?[0-9]
  • chcemy złapać dwójkę. Moglibyśmy to przerobić na 2[0-9]{2}|[1-9]?[0-9], ale wtedy złapałoby też np 299. więc to odpada
  • najpierw złapmy od 200-249, możemy to zrobić: 2[0-4][0-9]. Dodając do poprzedniego to: 2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]
  • teraz chcemy złapać ostatnie 250-255: 25[0-5]. Dodając do poprzedniego wychodzi nam 25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9].

Bardzo to przypomina TDD, gdzie każdy jeden taki podpunkt to byłby kolejny test który mógłbyś napisać, żeby wypracować algorytm samemu.

PS: Czyli w sumie rozwiązanie tożsame z tym przedstawionym przez @Spearhead .

2

Czy to jest jakiś realny problem czy tylko zadanie dla ćwiczenia umysłu? Dla kolegi pytam.

1

Tak tylko z ciekawości. Tabela ASCII dla 0 to 48 do 9 czyli 57. Jak to się ma do tego co tu widzę?

1

Czasem robię projekty, maja różny podtekst, to co tu rozmyślam to do sytemu komunikacji radiowej, wielokanałowy cyfrowy sterownik radiowy, na stole działa, w kanale, w powietrzu depesza zakodowana, zaszyfrowana opatrzona preambułą...mam różne urządzenia na koncie....alkomat, sterowniki kablowe, radiowe, oprogramowanie do poprawy jakości zapamiętywania dużych ilości informacji...dla dzieci, młodzieży i dorosłych...Pozdrawiam J

1

No dobrze, ale dlaczego w takim razie na wejściu ma być string? Skoro wiesz, że zakres to 0-255, to nie powinien to być ciąg bajtów?

0
robertos7778 napisał(a):

No dobrze, ale dlaczego w takim razie na wejściu ma być string? Skoro wiesz, że zakres to 0-255, to nie powinien to być ciąg bajtów?

robertos7778 nie wiem czy dobrze rozumiem ale na wejściu urządzeń wykonawczych będą nastawy powiedzmy 0..255,
kiedy generuje depesze komunikacyjna to: otrzymuje string który powiedzmy wygląda tak 0001786956**255**
i teraz mogę przesłać dane otwartym tekstem, mogę zaszyfrować to co wygenerował mikrokontroler nie wspominam
o kodowaniu, a mogę bo o to pytasz zamienić te cyfry powiedzmy na string *!&&$^*$# (string powinien być krótszy
niż string wejściowy) dodać sumę kontrolna, zaszyfrować zakodować , następnie wysłać
(suma kontrolna jest zaszyfrowana)...odbiornik dekoduje rozszyfrowuje wylicza sumę kontrolna jeżeli wszystkie
operacje przebiegają z opisem sukces mamy ponownie 0001786956**255**, z tego parsuje nastawy dane rejestracyjne,
producenta, kanał etc. jak również nastawę 255 dla urządzenia wykonawczego co oznacza powiedzmy ster kierunku
max w prawo...z rozdzielczością 256 pozycji. **Odp. tak to:(*!&&$^*$#) jest ciąg bajtów.**
0
Radosław Głębicki napisał(a):

Tak tylko z ciekawości. Tabela ASCII dla 0 to 48 do 9 czyli 57. Jak to się ma do tego co tu widzę?

Ascii 4 wygląda tak: 00000100, posiada lub nie posiada reprezentacji graficznej, ascii 48 to: 00110000 reprezentacja graficzna to: 0 (zero)
Powiedzmy że chcę przygotowac depesze komunikacyjną w której nr kanału:1,nr urządzenia nadawczego:0, operacja do wykonania:4(00000100) to w skrócie jeden znak ascii: 104 (01101000) reprezentacja graficzna H....wysyłam...
Odbieram, parsuje: nr kanału:1,nr urządzenia nadawczego:0, operacja do wykonania:4

1
JancioWodnik napisał(a):

Powiedzmy że chcę przygotowac depesze komunikacyjną w której nr kanału:1,nr urządzenia nadawczego:0, operacja do wykonania:4(00000100) to w skrócie jeden znak ascii: 104 (01101000) reprezentacja graficzna H....wysyłam...
Odbieram, parsuje: nr kanału:1,nr urządzenia nadawczego:0, operacja do wykonania:4

a czemu nie zakodujesz tego w pierwszym bajcie a reszta mogłaby być zwykłymi bajtami?
No i jak rozróżnisz "10,10" od "101,0"? Oba się zakodują jako 1010

0

a czemu nie zakodujesz tego w pierwszym bajcie a reszta mogłaby być zwykłymi bajtami?
No i jak rozróżnisz "10,10" od "101,0"? Oba się zakodują jako 1010

Tak, 1010 kiedy wysyłam taki zestaw to w systemie jest jasne ze parsuje 10 później kolejne 10 i składam w liczbę 10,10 ale to jest jeszcze inaczej 10,10 to powiedzmy w skali 0..255 to 32 wysyłam 032243 dla systemu jest jasne 10,10 odpowiada 032, a 101,0 odpowiada 243, jeszcze inaczej jeżeli chce wysłać zestaw 10,10;101,0 to po odebraniu, deszyfracji otrzymuje 10,10;101,0 parsuje pierwszą liczbę czyli znaki do średnika, parsuje druga wartość i mam 10,10 oraz 101,0
W przypadku string "125huya.,237" cyfrowo literowy, znaki diakrytyczne to szyfruje jak jest i wysyłam co mam, ale kiedy string to wyłącznie cyfry 001235687100255, mogę wysłać jak jest albo zakodować zaszyfrować i tak otrzymuje:

ScreenH0344.jpg
Wysyłam Result1 jest w kanale, w powietrzu(radio), albo kablem chociaż nie do końca bo nie jest zaszyfrowane ani zapakowane w kontener transportowy....
P.S.
Pierwsze dwa znaki w result1 nie posiadają reprezentacji graficznej chociaż tam jest ascii 0 - nul (00000000), Result1 jest cirka about połowę krótszy od In
ScreenH0345.jpg

2

Dlaczego mam wrażenie, że próbujesz wymyślić koło? Tylko jeszcze nie wiem jakie koło, bo twoje opisy są strasznie chaotyczne. Dlaczego nie skorzystasz z jakiegoś istniejącego, sprawdzonego protokołu?

0
robertos7778 napisał(a):

Dlaczego mam wrażenie, że próbujesz wymyślić koło? Tylko jeszcze nie wiem jakie koło, bo twoje opisy są strasznie chaotyczne. Dlaczego nie skorzystasz z jakiegoś istniejącego, sprawdzonego protokołu?

Jakie protokoły masz na myśli, może jakieś propozycje???

1

czy na pewno kodowanie stringu w ten sposób jest jednoznaczny?
1 vs. 12 vs. 123
i jak definiujesz dokładnie ASCII?

poza tym... sięganie po regexpy to może być tutaj armata na muchy.
jeśli masz ciąg znaków, to przecież możesz przelecieć znak po znaku i coś z tym zrobić dalej, skontruować po kolei kolejne liczby.

0

Wyżej w postach widać ze algorytm działa sprawnie. Jest to forma kodowania...

1

No to jeśli działa ci sprawnie, to w czym problem?

0

Witam, temat rozwiązany w pierwszym poście jeszcze raz dziękuje wszystkim za wypowiedzi na forum...
Pozdrawiam...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.