Problem ze stringiem

Dostaję to w paramsach takowego stringa \001[\001z\001B
przypisuję do atrybutu i nie mogę na tym wykonać metody scan(/00/) bo zawsze zwraca pustą tablice. Escapuje mi te ukośniki i jest kaka. ruby 1.8.7.
Jak to zrobić żeby traktował go jakby był w pojedynczych ciapkach?

Chwila - dostajesz stringa “backslash”+“zero”+“zero”+“jeden”, czy to jest wyynik metody inspect, czyli otrzymany param zaczyna się od bajtu o wartości jeden?

Próbowałeś wstawić dwa backslashe do regexpa? Genralnie trudno pytanie zrozumieć, bo nie wiem czy to co się wyświetla to jest to co napisałeś :slight_smile:

Z tego co widzę to w stringu są znaki o wartościach 1 (SOH - start of heading wg tablicy ASCII - \001 to jest jeden znak IMHO).

  1. Skąd masz takie dziwne znaki?
  2. Jeśli chcesz się pozbyć dziwnych znaków to użyj metody .gsub(/[^a-zA-Z0-9]/,"") oczywiście dostosuj to wyrażenie do tego co faktycznie ma dla Ciebie sens.

jeżeli w łańcuchu wypisanym na konsole jest “\001\002” to znaczy że łańcuch składa się z dwóch bajtów 0 oraz 1
najprościej to zobaczyć tak:

“\001\002”.split(//)
=> ["\001", “\002”]

“\001\002”.length
=> 2

“\001\002”[0]
=> 1

“\001\002”[1]
=> 2

Ten string to UTF-16BE.
Potrzebuję sprawdzić czy faktycznie tak jest. Ponieważ używam ruby 1.8.7 więc muszę to jakoś na około sprawdzać (chyba). Więc robie scan i jeśli mi pasuje do wzorca to wrzucam w Iconv i mam w UTF-8.

Jakiego wzorca chcesz szukać tym skanem? W pytaniu pokazałeś /00/ “slash”+“zero”+“zero”, co nie bardzo ma sens.

Jeśli chcesz znaleźć bajt o wartości jeden, spróbuj zwyczajnie: [code=ruby]str =~ /\001/

lub

str.include?("\001")[/code]

Myślałem o czymś typu /00.+00/ ale problemem jest że scna nic nie znajduje przez te / ] itp…
Problem rozwiązałem tak że do akcji trafia jeszcze parametr z nazwą kodowania i nie ma problemu. Ale jak przerobić “” (podwójne ciapki) na ‘’ (pojedyncze) nadal nie wiem :slight_smile:

może to:

str.gsub("\"", "'")

?

Kolega sevos mnie nie zrozumiał :slight_smile:

'\001[\002' =~ /\\00/ => 0

"\001[\002" =~ /\\00/ => nil
Gdy pobieram atrybut z bazy to jest on w “” a chcę go mieć w ‘’

Ja tu ciagle nie rozumiem. Co masz w Stringu? Bajt o kodzie jeden, czy cztery bajty, wyglądające jak wynik inspecta bajtu o kodzie jeden?

Regexp /00.+00/ dopasuje ci się do każdego stringu, w którym ktoś dwa razy wpisał po dwa zera. Na pewno nie tego chcesz.

Wygląda to mniej więcej tak.
Log z controllera Parameters: {"body"=>"\001Z\001\a\001z", "action"=>"create"
Potem status = Status.new status.body = Iconv.conv("UTF-8", "UTF-16BE", status.body) if status.body.jest_w_utf_16BE?
z braku pomysłu jest_w_utf16BE? zastąpiłem scan(/00.+00/) ale też nie działa o czym pisałem wyżej.

Oki, teraz już jest jasne. Nie wnikając w to, czy rzeczywiście string w utf16_be ma pierwszy bajt równy 1, powiem, że na szybko możesz zrobić właśnie tak:

.... if status.body[0] == 1

…a ten scan(/00.+00/) wyłapywał zupełnie inną rzecz, a mianowicie: dwa zera (dwa znaki ASCII o kodzie 48) potem dowolny ciąg czegokolwiek, a potem znów dwa zera.

Wiem że ten skan to nie to ale to z przyrównianiem do 1 to też nie bardzo bo to co akurat wkleiłem “\001Z\001\a\001z” to w UTF-8 - “Śćź”
Problem rozwiązałem inaczej (dostaje parametr ‘charset’ i już wiem czy konwertować czy nie)
Jednak inna rzecz mnie nurtuje jak w dosłownie takim stringu używać regexpów.

Przede wszystkim musisz rozróżniać co jest escapowaną postacią, a co nie jest; i czy szukasz jednego znaku, czy kilku. “\001” to jeden znak, ‘\001’ to cztery znaki.

Regexp traktuj jak String w podwójnych cudzysłowach, więc /\001/ dopasuje cztery znaki, /\001/ dopasuje jeden znak.

Zacznij od zabawy z literałami stringowymi. Musisz wiedzieć o co chodzi z pojedynczym cudzysłowem ', podwójnych ", a także z takimi dodatkami jak %Q{}, %q{}.

Dodam jeszcze, że Ruby 1.9 byłby tutaj pomocny, bo zamiast bawić się Iconv możesz zrobić te rzeczy bardziej elegancko (oczywiście Iconv jest używany pod spodem). W szczególności tyczy się to regexpów i metod np. zwracających długość łańcucha.