binary matching

Gustafsson <>
Wed Oct 2 09:22:32 CEST 2002


-module(bin_utils).                                                 
> -export([breakLines/1,extract/3,scan/6]).                           
>                                                                     
The reason that there is a bug in the scan function is that the default
size when you match something to a binary is all so in a 

Binary = <<1, 2, 3>>,
Pattern = <<1, 2>>,
<<Pattern/binary, Rest/binary>> = Binary

This will not result in a binding 
Rest = <<3>> but the matchinhg will fail

scan has to be rewritten something like this to work:

scan(<<>>, _Pattern, _Len, 0, 0, Acc) -> lists:reverse(Acc);        
scan(<<>>, _Pattern, _Len, Start, End, Acc) -> lists:reverse([End |
[Start |
Acc]]);                                                           
scan(Binary, Pattern, Len, Start, End, Acc)  ->
  Size = size(Pattern),
  case Binary of
    <<Pattern:Size/binary, Rest/binary>>
->                                                                    
      scan(Rest, Pattern, Len, End + Len, End + Len, [End | [Start |
Acc]]);
    <<_Nomatch, Rest/binary>> ->                              
      scan(Rest, Pattern, Len, Start, End + 8, Acc)
  end.



> breakLines(Binary) ->                                               
>      StartStop = scan(Binary, <<13,10>>, 16, 0, 0, []),             
>      extract(Binary, StartStop, []).                                
>                                                                     
> extract(<<>>, _Locs, Acc) -> lists:reverse(Acc);                    
> extract(Data, [Start, Stop | Rest], Acc) ->                         
>      Len = Stop - Start,                                            
>      %%%%%%%%%  Here is the problem %%%%%%%%%%%%                    
>      %% It does little good to get Line as an int %%                
>      <<Front:Start, Line:Len/binary, Back/binary>> = Data,          
>      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                    
>      extract(Back, Rest, [Line | Acc]).                             
>                                                                     
> scan(<<>>, _Pattern, _Len, 0, 0, Acc) -> lists:reverse(Acc);        
> scan(<<>>, _Pattern, _Len, Start, End, Acc) -> lists:reverse([End | 
[Start                                                                
> | Acc]]);                                                           
> scan(<<Pattern/binary, Rest/binary>>, Pattern, Len, Start, End, Acc)
->                                                                    
>      scan(Rest, Pattern, Len, End + Len, End + Len, [End | [Start | 
Acc]]);                                                               
> scan(Data, Pattern, Len, Start, End, Acc) ->                        
>      <<Nomatch, Rest/binary>> = Data,                               
>      scan(Rest, Pattern, Len, Start, End + 8, Acc).                 
>



More information about the erlang-questions mailing list