case string:substr(lists:reverse(String1), 1, length(String2)) of
String2 -> ok;
_ -> not_ok
end
I was thinking there must be a better way, but various attempts along the lines of
case String1 of
_ ++ String2 -> ok;
all returned "illegal pattern" errors. I couldn't find a clear explanation online of when exactly ++ is allowed in a pattern and when it's not, so I'm a bit stumped. Is there a better way?
thanks,
Dan
PS I'm aware of regexp and re, but my current environment is a hybrid of R12 and R13B so I'm a bit hesitant to involve either one right now.
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Although it doesn't actually answer the question you asked, you might
try something like lists:suffix(String2, String1).
Cheers.
k.
--
kevin montuori
> Suppose I want to test that a certain string String1 ends with a
> certain other string String2. The best I could come up with is:
>
> case string:substr(lists:reverse(String1), 1, length(String2)) of
> String2 -> ok;
> _ -> not_ok
> end
>
> I was thinking there must be a better way, but various attempts along
> the lines of case String1 of
> _ ++ String2 -> ok;
>
> all returned "illegal pattern" errors. I couldn't find a clear
> explanation online of when exactly ++ is allowed in a pattern and
> when it's not, so I'm a bit stumped. Is there a better way?
I can think of one using pattern matching,
is_substring(Substr, Substr) ->
true;
is_substring(String, Substr) ->
[_|T] = String,
p5(T, Substr).
you'd have to wrap it in a try ... catch for badmatch
--
Reynaldo
> On Mon, 27 Jun 2011 11:52:44 -0400
> Daniel Dormont <d...@greywallsoftware.com> wrote:
>
> > Suppose I want to test that a certain string String1 ends with a
> > certain other string String2. The best I could come up with is:
> >
> > case string:substr(lists:reverse(String1), 1, length(String2)) of
> > String2 -> ok;
> > _ -> not_ok
> > end
> >
> > I was thinking there must be a better way, but various attempts
> > along the lines of case String1 of
> > _ ++ String2 -> ok;
> >
> > all returned "illegal pattern" errors. I couldn't find a clear
> > explanation online of when exactly ++ is allowed in a pattern and
> > when it's not, so I'm a bit stumped. Is there a better way?
>
> I can think of one using pattern matching,
>
> is_substring(Substr, Substr) ->
> true;
> is_substring(String, Substr) ->
> [_|T] = String,
> p5(T, Substr).
Oops, that should be:
is_substring(String, Substr) ->
[_|T] = String,
is_substring(T, Substr).
There are no strings in Erlang! :-)
> case string:substr(lists:reverse(String1), 1, length(String2)) of
> String2 -> ok;
> _ -> not_ok
> end
Kevin already pointed you to lists:suffix/2 which is good if suffix
isn't statically known, and very easy on the eyes too. If suffix is
known you could do:
has_suffix(L) ->
has_suffix2(lists:reverse(L)).
has_suffix2("xiffus" ++ _) ->
true;
has_suffix2(_) ->
false.
Which I think answers your other question. More precisely, AFAIU this
has_suffix2("xiffus" ++ _)
is just syntactic sugar for
has_suffix2([$x, $i, $f, $f, $u, $s | _])
So in a way you could perhaps say "++" isn't really supported in pattern
matching (but other will know this with more certainty). One doesn't see
"++" used very often overall, in my experience.
Also, this would have been so much cheaper (but harder to read) if you
used binaries to represent strings:
has_suffix(S, B) ->
has_suffix2(byte_size(B) - byte_size(S), S, B).
has_suffix2(N, _, _) when N < 0 ->
false;
has_suffix2(N, S, <<_:N/binary, D/binary>>) ->
S == D.
Or somesuch, you get the idea.
HTH,
-- Jachym
> # Daniel Dormont 2011-06-27:
>> Suppose I want to test that a certain string String1 ends with a certain
>> other string String2. The best I could come up with is:
>
> There are no strings in Erlang! :-)
>
Right, fair enough.
>> case string:substr(lists:reverse(String1), 1, length(String2)) of
>> String2 -> ok;
>> _ -> not_ok
>> end
>
> Kevin already pointed you to lists:suffix/2 which is good if suffix
> isn't statically known, and very easy on the eyes too. If suffix is
> known you could do:
>
> has_suffix(L) ->
> has_suffix2(lists:reverse(L)).
>
> has_suffix2("xiffus" ++ _) ->
> true;
> has_suffix2(_) ->
> false.
>
I was not familiar with lists:suffix. I am now :) and it works fine for my purposes.
> Which I think answers your other question. More precisely, AFAIU this
>
> has_suffix2("xiffus" ++ _)
>
> is just syntactic sugar for
>
> has_suffix2([$x, $i, $f, $f, $u, $s | _])
>
> So in a way you could perhaps say "++" isn't really supported in pattern
> matching (but other will know this with more certainty). One doesn't see
> "++" used very often overall, in my experience.
>
Ok.
> Also, this would have been so much cheaper (but harder to read) if you
> used binaries to represent strings:
>
> has_suffix(S, B) ->
> has_suffix2(byte_size(B) - byte_size(S), S, B).
>
> has_suffix2(N, _, _) when N < 0 ->
> false;
> has_suffix2(N, S, <<_:N/binary, D/binary>>) ->
> S == D.
>
Right, unfortunately in the place where my module will be called, the string values are in lists, not binaries.
> Or somesuch, you get the idea.
>
Dan
> Suppose I want to test that a certain string String1 ends with a certain other string String2. The best I could come up with is:
>
> case string:substr(lists:reverse(String1), 1, length(String2)) of
> String2 -> ok;
> _ -> not_ok
> end
>
> I was thinking there must be a better way, but various attempts along the lines of
> case String1 of
> _ ++ String2 -> ok;
>
> all returned "illegal pattern" errors. I couldn't find a clear explanation online of when exactly ++ is allowed in a pattern and when it's not, so I'm a bit stumped.
Section 7.4 of the reference manual is the place where it says ++ is allowed
as a pattern, and the only thing it allows on the left of ++ is an explicit
string literal. A pattern like
"foo"++X
is just shorthand for
[$f,$o,$o|X]
If you want to check whether String1 ends with String2,
(a) you're going to need an even number of calls to lists:reverse/1
(b) you are going to be kicking yourself that you didn't read the
documentation for the 'lists' module
http://www.erlang.org/doc/man/lists.html
because
lists:suffix(String2, String1)
does exactly what you want (modulo returning 'true' or 'false').
Section 7.4 of the reference manual is the place where it says ++ is allowed
On 28/06/2011, at 3:52 AM, Daniel Dormont wrote:
> Suppose I want to test that a certain string String1 ends with a certain other string String2. The best I could come up with is:
>
> case string:substr(lists:reverse(String1), 1, length(String2)) of
> String2 -> ok;
> _ -> not_ok
> end
>
> I was thinking there must be a better way, but various attempts along the lines of
> case String1 of
> _ ++ String2 -> ok;
>
> all returned "illegal pattern" errors. I couldn't find a clear explanation online of when exactly ++ is allowed in a pattern and when it's not, so I'm a bit stumped.
as a pattern, and the only thing it allows on the left of ++ is an explicit
string literal. A pattern like
"foo"++X
is just shorthand for
[$f,$o,$o|X]
If you want to check whether String1 ends with String2,
(a) you're going to need an even number of calls to lists:reverse/1
(b) you are going to be kicking yourself that you didn't read the
documentation for the 'lists' module
http://www.erlang.org/doc/man/lists.html
because
lists:suffix(String2, String1)
does exactly what you want (modulo returning 'true' or 'false').