Using map keys in Regex

Hi, Thanks to all for all the great resources. I am new.

I am trying to use map keys for a lookaround in Regex.run. #{k} yields nil. If I put “GOOG” in it’s place, I retrieve the number (price) from the csv data in the format I want.

How would you attack this?

defmodule Yahoo do  
  Application.ensure_all_started :inets

  def update_prices do
get_quote()
|>pull_price
|>Map.new
|>IO.inspect
  end

  def get_quote do
{:ok, resp} = :httpc.request(:get, {'http://download.finance.yahoo.com/d/quotes.csv?s=YHOO,GOOG,AAPL&f=sl1d1t1c1ohgv&e=.csv', []}, [], [body_format: :binary])
{{_, 200, 'OK'}, _headers, body} = resp
body
  end

  def pull_price(body) do
Enum.map(%{"GOOG" => 10, "AAPL" => 30, "YHOO" => 15}, fn {k,v} ->
  {k, Regex.run(~r/(?<=#{k},)[0-9]*\.[0-9]+(?=,)/x, body)} end)
  end 

end

That is because you are using the static regex constructor, the sigil ~r. :slight_smile:

This is actually a macro that runs at compile-time to generate a regex parser and inlines it for speed so it does not always need to recreate it, which is awesome and fast!

However, you are trying to dynamically create a regex from a string, so you should actually be using the Regex module (compile specifically) to create your new regex each time (I think you can actually pass a string to some regex functions and they compile on-the-fly, check?) instead of the ~r sigil. :slight_smile:

The issue is that k does not exist at compile-time, so the static macro is compiled with nil there, though to be honest I’d think that ~r should throw an error for such a thing, maybe @josevalim has an idea on how? :slight_smile:

1 Like

1000 Thanks! Works perfectly

  def pull_price(body) do
    Enum.map(%{"GOOG" => 10, "AAPL" => 30, "YHOO" => 15}, fn {k,v} ->
      {k, create_regex(k)|>Regex.run(body)} end)
  end 

  def create_regex(k) do
    {:ok, regex} = Regex.compile("(?<=\"#{k}\",)[0-9]*\.[0-9]+(?=,)")
    regex
  end
1 Like