Binary String pattern matching

Hugo Mills hugo@REDACTED
Thu Dec 10 20:47:20 CET 2020


On Thu, Dec 10, 2020 at 06:44:54PM +0100, Java House wrote:
> Thank you for the tip.
> Is there any way to do it on the module level, or did you mean to just
> create the regex and compile it before start checking the list of records?

   In the past, I've written a small escript that compiles the regex
and then writes the compiled regex to a macro definition in a .hrl
file. You can then use the macro as a compiled regex.

   This is specific to a given Erlang release -- you can't build the
code on one version and have it run on another -- but it does
work.

   It's probably easier to put it in a persistent term, though, or
your process state.

   Hugo.

> Στις Πέμ, 10 Δεκ 2020 στις 5:26 μ.μ., ο/η Karl Velicka <
> karolis.velicka@REDACTED> έγραψε:
> 
> > Hi,
> >
> > If you're going with compiled regex, you should probably pass it to the
> > function and cache it somewhere outside - as it stands, you keep
> > recompiling the regex for every invocation of your parser which may well be
> > slower than just not bothering to compile it at all.
> >
> > Karl
> >
> > On Thu, 10 Dec 2020 at 14:57, Java House <java4dev@REDACTED> wrote:
> >
> >> Thank you for the proposal, I will try that as well.
> >> In the meantime I did this
> >> currrency_to_credits({cur, Value}, Acc) ->
> >> Regexp = "(.*)(CHF|EUR|US)",
> >> {ok, MP} = re:compile(Regexp),
> >> case re:run(Value, MP, [global, {capture,[1,2], binary}]) of
> >> {match,[[V,C]]} -> currrency_to_credits(cur, V, U, Acc);
> >> nomatch -> Acc
> >> end;
> >>
> >> Στις Πέμ, 10 Δεκ 2020 στις 9:04 π.μ., ο/η Valdimar Kristjánsson <
> >> nisbus@REDACTED> έγραψε:
> >>
> >>> You could reverse it first and then match on the reversed symbol:
> >>>
> >>> Data from the provider:
> >>>
> >>>> Reversed = list_to_binary(lists:reverse(binary_to_list(<<"1234EUR">>))).
> >>>
> >>>
> >>>
> >>> Reverse the Currency name in the match
> >>>
> >>>>  currency_to_credits({cur, <<"RUE", Reversed/binary>>}, Acc) ->
> >>>>    {eur, Acc + A};
> >>>
> >>>
> >>> Probably not the most performant but at least it solves the problem.
> >>>
> >>> Best,
> >>> nisbus
> >>>
> >>> On Thu, Dec 10, 2020 at 8:16 AM Java House <java4dev@REDACTED> wrote:
> >>>
> >>>> Hi
> >>>>
> >>>> yes the binary string is of the format <<"xxx">>
> >>>>
> >>>> <<"3123CHF">>
> >>>>> <<"341424343EUR">>
> >>>>> <<"14143US">>
> >>>>>
> >>>>  Thank you for the answer.
> >>>> So is there any other way?
> >>>> erlang provides the binary_to_list, is there any way to achieve the
> >>>> same with a list becasue I tried similare patterns with list and it does
> >>>> not work e.g
> >>>> [V|T] this will always match the first character of the string to V
> >>>> and [V|"CHF"] does not work neither.
> >>>>
> >>>> Best
> >>>> Nikolas
> >>>>
> >>>> Στις Τετ, 9 Δεκ 2020 στις 7:58 μ.μ., ο/η kuna.prime <
> >>>> kuna.prime@REDACTED> έγραψε:
> >>>>
> >>>>> HI,
> >>>>>
> >>>>> first of all binary string is of form <<"3123CHF">> and not
> >>>>> <<3123CHF>> i'm just stating it in case there was a mistake in the first
> >>>>> mail
> >>>>>
> >>>>> to answer your questio in order to pattern match you need to know the
> >>>>> size of field you are matching so
> >>>>>
> >>>>> <<X:4/binary, "CHF">> = <<"3123CHF">>.
> >>>>>
> >>>>> will match fist 4 bytes and interpret that as new binary (X).
> >>>>>
> >>>>>
> >>>>> Sent with ProtonMail <https://protonmail.com> Secure Email.
> >>>>>
> >>>>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
> >>>>> On Wednesday, December 9, 2020 7:28 PM, Java House <java4dev@REDACTED>
> >>>>> wrote:
> >>>>>
> >>>>> there is a typo in the example
> >>>>> currrency_to_credits({cur, << Value , "CHF">>}, Acc)
> >>>>>   when Value >= <<"1000">>, Value =< <<"10000">> ->
> >>>>>      {chf, Acc + Value };
> >>>>> currrency_to_credits({cur, << Value , "EUR">>}, Acc)
> >>>>>   when Value >= <<"1000">>, Value =< <<"10000">> ->
> >>>>>      {eur, Acc + Value };
> >>>>> currrency_to_credits({cur, << Value , "US">>}, Acc)
> >>>>>   when Value >= <<"1000">>, Value =< <<"10000">> ->
> >>>>>      {us, Acc + Value };
> >>>>>
> >>>>> Στις Τετ, 9 Δεκ 2020 στις 7:17 μ.μ., ο/η Java House <
> >>>>> java4dev@REDACTED> έγραψε:
> >>>>>
> >>>>>> Hello all
> >>>>>>
> >>>>>> I am learning Erlang and have stuck to the following problem.
> >>>>>> How to write a function with pattern matching when the parameter is a
> >>>>>> binary string.
> >>>>>>
> >>>>>> I have a list of binary strings e.g.
> >>>>>> <<3123CHF>>
> >>>>>> <<341424343EUR>>
> >>>>>> <<14143US>>
> >>>>>>
> >>>>>> I am trying to create a function that matches according to a pattern.
> >>>>>>
> >>>>>> currrency_to_credits({cur, <<A, "CHF">>}, Acc)
> >>>>>>   when Value >= <<"1000">>, Value =< <<"10000">> ->
> >>>>>>      {chf, Acc + A};
> >>>>>> currrency_to_credits({cur, <<A, "EUR">>}, Acc)
> >>>>>>   when Value >= <<"1000">>, Value =< <<"10000">> ->
> >>>>>>      {eur, Acc + A};
> >>>>>> currrency_to_credits({cur, <<A, "US">>}, Acc)
> >>>>>>   when Value >= <<"1000">>, Value =< <<"10000">> ->
> >>>>>>      {us, Acc + A};
> >>>>>>
> >>>>>> But this does not seem to be the right way.
> >>>>>> How can I create a pattern for binary string?
> >>>>>> will it work better for list string? How?
> >>>>>>
> >>>>>> Thank you
> >>>>>> Nikolas
> >>>>>>
> >>>>>
> >>>>>

-- 
Hugo Mills             | Modern medicine does not treat causes: headaches are
hugo@REDACTED carfax.org.uk | not caused by a paracetamol deficiency.
http://carfax.org.uk/  |
PGP: E2AB1DE4          |


More information about the erlang-questions mailing list