string.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 360 行

ERL
360
字号
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%-module(string).-export([len/1,equal/2,concat/2,chr/2,rchr/2,str/2,rstr/2,index/2,	 span/2,cspan/2,substr/2,substr/3,tokens/2,chars/2,chars/3]).-export([copies/2,words/1,words/2,strip/1,strip/2,strip/3,	 sub_word/2,sub_word/3,left/2,left/3,right/2,right/3,	 sub_string/2,sub_string/3,centre/2,centre/3]).-export([re_sh_to_awk/1,re_parse/1,re_match/2,re_sub/3,re_gsub/3,re_split/2]).-export([to_upper/1, to_lower/1]).-deprecated([{re_sh_to_awk,1},{re_parse,1},{re_match,2},{re_sub,3},             {re_gsub,3},{re_split,2},{index,2}]).-import(lists,[reverse/1,member/2]).%% Robert's bit%% len(String)%%  Return the length of a string.len(S) -> length(S).%% equal(String1, String2)%%  Test if 2 strings are equal.equal(S, S) -> true;equal(_, _) -> false.%% concat(String1, String2)%%  Concatenate 2 strings.concat(S1, S2) -> S1 ++ S2.%% chr(String, Char)%% rchr(String, Char)%%  Return the first/last index of the character in a string.chr(S, C) when is_integer(C) -> chr(S, C, 1).chr([C|_Cs], C, I) -> I;chr([_|Cs], C, I) -> chr(Cs, C, I+1);chr([], _C, _I) -> 0.rchr(S, C) when is_integer(C) -> rchr(S, C, 1, 0).rchr([C|Cs], C, I, _L) ->			%Found one, now find next!    rchr(Cs, C, I+1, I);rchr([_|Cs], C, I, L) ->    rchr(Cs, C, I+1, L);rchr([], _C, _I, L) -> L.%% str(String, SubString)%% rstr(String, SubString)%% index(String, SubString)%%  Return the first/last index of the sub-string in a string.%%  index/2 is kept for backwards compatibility.str(S, Sub) when is_list(Sub) -> str(S, Sub, 1).str([C|S], [C|Sub], I) ->    case prefix(Sub, S) of	true -> I;	false -> str(S, [C|Sub], I+1)    end;str([_|S], Sub, I) -> str(S, Sub, I+1);str([], _Sub, _I) -> 0.rstr(S, Sub) when is_list(Sub) -> rstr(S, Sub, 1, 0).rstr([C|S], [C|Sub], I, L) ->    case prefix(Sub, S) of	true -> rstr(S, [C|Sub], I+1, I);	false -> rstr(S, [C|Sub], I+1, L)    end;rstr([_|S], Sub, I, L) -> rstr(S, Sub, I+1, L);rstr([], _Sub, _I, L) -> L.prefix([C|Pre], [C|String]) -> prefix(Pre, String);prefix([], String) when is_list(String) -> true;prefix(Pre, String) when is_list(Pre), is_list(String) -> false.index(S, Sub) -> str(S, Sub).%% span(String, Chars) -> Length.%% cspan(String, Chars) -> Length.span(S, Cs) when is_list(Cs) -> span(S, Cs, 0).span([C|S], Cs, I) ->    case member(C, Cs) of	true -> span(S, Cs, I+1);	false -> I    end;span([], _Cs, I) -> I.cspan(S, Cs) when is_list(Cs) -> cspan(S, Cs, 0).cspan([C|S], Cs, I) ->    case member(C, Cs) of	true -> I;	false -> cspan(S, Cs, I+1)    end;cspan([], _Cs, I) -> I.%% substr(String, Start)%% substr(String, Start, Length)%%  Extract a sub-string from String.substr(String, 1) when is_list(String) ->     String;substr(String, S) when is_integer(S), S > 1 ->    substr2(String, S).substr(String, S, L) when is_integer(S), S >= 1, is_integer(L), L >= 0 ->    substr1(substr2(String, S), L).substr1([C|String], L) when L > 0 -> [C|substr1(String, L-1)];substr1(String, _L) when is_list(String) -> [].	     %Be nice!substr2(String, 1) when is_list(String) -> String;substr2([_|String], S) -> substr2(String, S-1).%% tokens(String, Seperators).%%  Return a list of tokens seperated by characters in Seperators.tokens(S, Seps) ->    tokens1(S, Seps, []).tokens1([C|S], Seps, Toks) ->    case member(C, Seps) of	true -> tokens1(S, Seps, Toks);	false -> tokens2(S, Seps, Toks, [C])    end;tokens1([], _Seps, Toks) ->    reverse(Toks).tokens2([C|S], Seps, Toks, Cs) ->    case member(C, Seps) of	true -> tokens1(S, Seps, [reverse(Cs)|Toks]);	false -> tokens2(S, Seps, Toks, [C|Cs])    end;tokens2([], _Seps, Toks, Cs) ->    reverse([reverse(Cs)|Toks]).chars(C, N) -> chars(C, N, []).chars(C, N, Tail) when N > 0 ->    chars(C, N-1, [C|Tail]);chars(C, 0, Tail) when is_integer(C) ->    Tail.%% Torbj鰎n's bit.%%% COPIES %%%copies(CharList, Num) when is_list(CharList), Num >= 0 ->    copies(CharList, Num, []).copies(_CharList, 0, R) ->    R;copies(CharList, Num, R) ->    copies(CharList, Num-1, CharList++R).%%% WORDS %%%words(String) -> words(String, $\s).words(String, Char) when is_integer(Char) ->    w_count(strip(String, both, Char), Char, 0).w_count([], _, Num) -> Num+1;w_count([H|T], H, Num) -> w_count(strip(T, left, H), H, Num+1);w_count([_H|T], Char, Num) -> w_count(T, Char, Num).%%% SUB_WORDS %%%sub_word(String, Index) -> sub_word(String, Index, $\s).sub_word(String, Index, Char) when is_integer(Index), is_integer(Char) ->    case words(String, Char) of	Num when Num < Index ->	    [];	_Num ->	    s_word(strip(String, left, Char), Index, Char, 1, [])    end.s_word([], _, _, _,Res) -> reverse(Res);s_word([Char|_],Index,Char,Index,Res) -> reverse(Res);s_word([H|T],Index,Char,Index,Res) -> s_word(T,Index,Char,Index,[H|Res]);s_word([Char|T],Stop,Char,Index,Res) when Index < Stop ->     s_word(strip(T,left,Char),Stop,Char,Index+1,Res);s_word([_|T],Stop,Char,Index,Res) when Index < Stop ->     s_word(T,Stop,Char,Index,Res).%%% STRIP %%%strip(String) -> strip(String, both).strip(String, left) -> strip_left(String, $\s);strip(String, right) -> strip_right(String, $\s);strip(String, both) ->    strip_right(strip_left(String, $\s), $\s).strip(String, right, Char) -> strip_right(String, Char);strip(String, left, Char) -> strip_left(String, Char);strip(String, both, Char) ->    strip_right(strip_left(String, Char), Char).strip_left([Sc|S], Sc) ->    strip_left(S, Sc);strip_left([_|_]=S, Sc) when is_integer(Sc) -> S;strip_left([], Sc) when is_integer(Sc) -> [].strip_right([Sc|S], Sc) ->    case strip_right(S, Sc) of	[] -> [];	T  -> [Sc|T]    end;strip_right([C|S], Sc) ->    [C|strip_right(S, Sc)];strip_right([], Sc) when is_integer(Sc) ->    [].%%% LEFT %%%left(String, Len) when is_integer(Len) -> left(String, Len, $\s).left(String, Len, Char) when is_integer(Char) ->    Slen = length(String),    if	Slen > Len -> substr(String, 1, Len);	Slen < Len -> l_pad(String, Len-Slen, Char);	Slen =:= Len -> String    end.l_pad(String, Num, Char) -> String ++ chars(Char, Num).%%% RIGHT %%%right(String, Len) when is_integer(Len) -> right(String, Len, $\s).right(String, Len, Char) when is_integer(Char) ->    Slen = length(String),    if	Slen > Len -> substr(String, Slen-Len+1);	Slen < Len -> r_pad(String, Len-Slen, Char);	Slen =:= Len -> String    end.r_pad(String, Num, Char) -> chars(Char, Num, String).%%% CENTRE %%%centre(String, Len) when is_integer(Len) -> centre(String, Len, $\s).centre(String, 0, Char) when is_list(String), is_integer(Char) ->    [];                       % Strange cases to centre stringcentre(String, Len, Char) when is_integer(Char) ->    Slen = length(String),    if	Slen > Len -> substr(String, (Slen-Len) div 2 + 1, Len);	Slen < Len ->	    N = (Len-Slen) div 2,	    r_pad(l_pad(String, Len-(Slen+N), Char), N, Char);	Slen =:= Len -> String    end.%%% SUB_STRING %%%sub_string(String, Start) -> substr(String, Start).sub_string(String, Start, Stop) -> substr(String, Start, Stop - Start + 1).%% The Regular Expression Matching Functions.%%%%  These have been rewritten. As their interface has changed slightly%%  (much to the better) I have moved them to a new module 'regexp' to%%  avoid another "interface war" about something which doesn't%%  serioulsy affect that many people. This interface is kept for%%  backwards compatibility so I don't get shot for that as well.%%%%  /Robert Virdingre_sh_to_awk(ShellRegExp) -> regexp:sh_to_awk(ShellRegExp).re_parse(RegExp) ->    case regexp:parse(RegExp) of	{ok,RE} -> {regexp,RE};	{error,E} -> {error,E}     end.re_match(String, RegExp) ->    case regexp:match(String, RegExp) of	{match,Start,Len} -> {match,substr(String, Start, Len),Start};	nomatch -> nomatch;	{error,E} -> {error,E}    end.re_sub(String, RegExp, New) ->    case regexp:sub(String, RegExp, New) of	{ok,Res,_N} -> {ok,Res};	{error,E} -> {error,E}    end.re_gsub(String, RegExp, New) ->    case regexp:gsub(String, RegExp, New) of	{ok,Res,_N} -> {ok,Res};	{error,E} -> {error,E}    end.re_split(String, RegExp) -> regexp:split(String, RegExp).%% The long awaited to_upper and to_lower%% ISO/IEC 8859-1 (latin1) letters are converted, others are ignored%%to_lower_char(C) when is_integer(C),  C >= $A, C =< $Z ->    C + 32;to_lower_char(C) when is_integer(C),  C >= 16#C1, C =< 16#D6 ->    C + 32;to_lower_char(C) when is_integer(C),  C >= 16#D8, C =< 16#DE ->    C + 32;to_lower_char(C) ->    C.to_upper_char(C) when is_integer(C),  C >= $a, C =< $z ->    C - 32;to_upper_char(C) when is_integer(C),  C >= 16#E1, C =< 16#F6 ->    C - 32;to_upper_char(C) when is_integer(C),  C >= 16#F8, C =< 16#FE ->    C - 32;to_upper_char(C) ->    C.to_lower(S) when is_list(S) ->    [to_lower_char(C) || C <- S];to_lower(C) when is_integer(C) ->    to_lower_char(C).to_upper(S) when is_list(S) ->    [to_upper_char(C) || C <- S];to_upper(C) when is_integer(C) ->    to_upper_char(C).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?