elbasti

elbasti

Complicated binary pattern matching in function heads

I’m trying to implement some functionality by pattern matching purely as a learning exercise to familiarize myself with bitstrings/charslists/binaries.

Imagine I want to write a function parse_symbol that takes the symbol for a security and parses it into it’s constituent parts.

A security symbol is a string that looks like this:
"NU 05/19/2023 4.50 P", or "AAPL 03/31/2023 145.00 C"

Each of those symbols is made up of {stock ticker} {expiration date} {strike price} {option type}

So AAPL 03/31/2023 145.00 C is an “apple call option, with a $145 strike price, and an expiration date of 03/31/2023”.

The stock ticker part is of variable length: it could be one character (F is the symbol for the Ford Motor Company) or multiple. The “Option type” could be "C" for a call option or "P" for a put.

It’s relatively simple to write a regex that parses out the components of the symbol. Is it possible to parse them out in a function head by pattern matching?

So something like:

def parse_symbol(<<ticker," ", month,"/",day,"/",year," ",strike," ",type>>) do
    %{ticker: ticker, strike: strike, type: type}
end

Warning: I know that the above code is probably broken/gobledeegook in all sorts of ways, I’m just trying to grok how binaries work :slight_smile:

Marked As Solved

hst337

hst337

It is not possible to write a single pattern to parse this string. However, it is possible to write a pattern for dates matching:

[ticker, date, price, option] = String.split(input, " ")
<<month :: binary-size(2), "/", day :: binary-size(2), "/", year :: binary-size(4)>> = date
price = String.to_float(price) # Or decimal parse
[year, month, day] = Enum.map([year, month, day], &String.to_integer/1)

Also Liked

hst337

hst337

Yes, it is variable length. Binary pattern matching was designed to help in the development of fixed-offset binary protocols.

bottlenecked

bottlenecked

You could if you wanted to… but you’d have to know min and max number of characters for the ticker length.

Example

# ticker of length = 2
<<ticker::binary-size(2)," ",rest::binary>> = "NU 05/19/2023 4.50 P"

#ticker of length = 4
<<ticker::binary-size(4)," ",rest::binary>> = "AAPL 03/31/2023 145.00 C"

So basically you’d have to create as many function heads for parse_symbol/1 as there are variations in the length of the ticker (assuming everything else is of constant length). But this assumption probably doesn’t hold true for the price (again, assuming you’re looking to extract it using pattern matching) - so you’d need to combine with some other approach if you need to read all values out of the security symbol

ntodd

ntodd

I know you are doing this as an exercise, but to me this sounds like a good fit for a parser combinator. Look into how NimbleParsec handles it. You can view the compiled binary pattern matching clauses with debug: true. That might help you with your task.

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement