String splitting problems in Erlang

11,003

Solution 1

Since strings in Erlang are just a list() of integer() the test in the fun will be made if the item is an atom() when it is in fact an integer(). If the test is changed to look for letters it works:

29> lists:splitwith(fun (C) -> (C >= $a) and (C =< $Z)  end, atom_to_list(ms444)).
{"ms","444"}

Solution 2

You might want to have a look at the string module documentation:

http://www.erlang.org/doc/man/string.html

The following function might interest you:

tokens(String, SeparatorList) -> Tokens

Solution 3

An atom in erlang is a named constant and not a variable (or not like a variable is in an imperative language). You should really not create atoms in dynamic fashion (that is, don't convert things to atoms at runtime)

They are used more in pattern matching and send recive code.

Pid ! {matchthis, X}


recive
{foobar,Y} -> doY(Y);
{matchthis,X} -> doX(X);
Other -> doother(Other)
end

A variable, like X could be set to an atom. For example X=if 1==1 -> ok; true -> fail end. I could suffer from poor imagination but I can't think of a way why you would like to parse atom. You should be in charge of what atoms you write and not use list_to_atom(CharIntegerList).

Can you perhaps give a more overview of what you like to accomplish?

Share:
11,003
Fylke
Author by

Fylke

Test- and test environment specialist currently working with DAL A software on the JAS 39 Gripen E fighter jet as a consultant at SAAB. My interests are mainly in automation, testing and concurrency. My favorite language is Erlang, but I'm proficient in Java, MatLab, Shell Script, C, Python, XSLT/XPath and Groovy. Somewhat in falling order of proficiency. I really like travelling and have worked stints in both China and Japan. Have been to most of Asia and Oceania - hit me up for tips. Met my wife while scuba diving in the Philippines - I was working in Japan at the time, and she was working in China. Now we're living in Sweden.

Updated on June 04, 2022

Comments

  • Fylke
    Fylke almost 2 years

    I've been playing around with the splitting of atoms and have a problem with strings. The input data will always be an atom that consists of some letters and then some numbers, for instance ms444, r64 or min1. Since the function lists:splitwith/2 takes a list the atom is first converted into a list:

    24> lists:splitwith(fun (C) -> is_atom(C) end, [m,s,4,4,4]).
    {[m,s],[4,4,4]}
    25> lists:splitwith(fun (C) -> is_atom(C) end, atom_to_list(ms444)).
    {[],"ms444"}
    26> atom_to_list(ms444).
    "ms444"
    

    I want to separate the letters from the numbers and I've succeeded in doing that when using a list, but since I start out with an atom I get a "string" as result to put into my splitwith function...

    Is it interpreting each item in the list as a string or what is going on?

  • gleber
    gleber over 14 years
    There is no need to use atom_to_list/1 here. Just write "ms444" (with quotes) and you will get a string (list of integers).
  • Fylke
    Fylke over 14 years
    No, wouldn't work, I need all characters intact. There are no "throwaway" characters in there.
  • Fylke
    Fylke over 14 years
    Well agreed, but it looks wonky if the atom in question is a variable as it would be in a real program. Would it even work then?
  • Fylke
    Fylke over 14 years
    What I'm doing is parsing an ASN1 spec that has been compiled into erlang and where certain enums have been translated into atoms, ms480 for instance, means that there should be a 480 ms delay between sendings of a certain signal.
  • Feek
    Feek over 14 years
    ah. I suppose its impossible to make that "any other way". (To mee it seems a bit odd to have the specs as atoms that way ms480 instead of {ms,480}but we are all slaves to the masters.) So what happens is that someone parses text into atoms, you take the atoms and convert them to strings,s split them and I suppose that you after that convert "480" into a number.
  • Fylke
    Fylke almost 12 years
    Yes there is, ms444 is an atom.