В Perl unpack
можно использовать для аккуратного разделения строки полей фиксированной длины на части. Ниже приводится пример его использования для достижения этой цели:
# get a 5-byte string, skip 3, then grab 2 8-byte strings, then the rest
my ($leading, $s1, $s2, $trailing) = unpack("A5 x3 A8 A8 A*", $data);
Есть ли эквивалент unpack
в Clojure?
Я также хотел бы отметить, что в JVM строки не являются механизмом передачи двоичных данных, поскольку pack
и unpack
используют их в Perl. Строки кодируются UTF-16, поэтому существуют двоичные строки, которые они не могут представить. Если вам нужен очень простой анализатор только строк, то регулярные выражения — разумный выбор, как рекомендует Юджин. Если вам нужно что-то кроме A
и x
, вам нужно научиться обращаться с двоичными данными.
Учитывая, насколько зрелым является Clojure, мне было любопытно, как он обрабатывает двоичные данные, упакованные в строки. Я хотел посмотреть, есть ли что-то готовое, что я мог бы использовать, не создавая собственный код. Я использовал код распаковки Perl как чисто иллюстративный пример готового одноэтапного подхода к обработке двоичных данных. Спасибо за ответ.
Нет, и соответствующего pack
нет.
Я бы использовал RegEx. Хотя я не могу сказать, насколько точна эта альтернатива, поскольку я не знаю Perl и того, как он обрабатывает многобайтовые символы в строках.
;; If you prefer named groups.
(let [data "xxxxx___yyyyyyyyzzzzzzzz1234awerasdf"
pattern #"(?<leading>.{5}).{3}(?<s1>.{8})(?<s2>.{8})(?<trailing>.*)"
matcher (re-matcher pattern data)]
(re-find matcher)
(into {}
(map (fn [[n idx]]
[(keyword n) (.group matcher ^long idx)]))
(.namedGroups matcher)))
;; If you prefer to rely on positions.
(let [data "xxxxx___yyyyyyyyzzzzzzzz1234awerasdf"
pattern #"(.{5}).{3}(.{8})(.{8})(.*)"
[_ leading s1 s2 trailing] (re-matches pattern data)]
{:leading leading
:s1 s1
:s2 s2
:trailing trailing})
Мне кажется, это будет легко реализовать.