2016-02-10 23 views
5

Desidero confrontare due stringhe che contengono simboli di diversi alfabeti (ad esempio russo e inglese). Voglio che i simboli che appaiono allo stesso modo siano considerati uguali tra loro.Confronto di stringhe con simboli di diversi alfabeti

E.g. nella parola "mamma" la lettera "o" viene dall'alfabeto inglese (codice 043E in Unicode), e nel mondo "Mоm" la lettera "о" viene dall'alfabeto russo (codice 006F in Unicode). Quindi ("Mom" = "Mоm") => falso, ma voglio che sia vero. C'è qualche funzione SAS standard o dovrei wright una macro per farlo.

Grazie!

risposta

1

Farei così:

Prima vorrei fare la mappa. Intendo quale lettera in lingua russa corrisponde a quale lettera in inglese. Esempio:
б = b
в = v
...

vorrei conservare questa mappa in una tabella separata o come macroVars. Quindi creo un ciclo macro, con funzione tranwrd, che esegue il looping della mappa, che è stata creata.

Esempio qui potrebbe essere così.

data _null_; 
    stringBefore = "без"; 
    stringAfter = tranwrd(stringBefore,"а","a"); 
    stringAfter = tranwrd(stringAfter,"б","b"); 
    stringAfter = tranwrd(stringAfter,"в","v"); 
... 
run; 

Dopo questa trasformazione Penso che si possa confrontare le corde.

0

Ho anche codificato alcune funzioni per gestire gli errori di stampa del layout della tastiera. Ecco il codice:

/***************************************************************************/ 
/* FUNCTION count_rus_letters RETURNS NUMBER OF CYRILLIC LETTERS IN STRING */ 
/***************************************************************************/ 
proc fcmp outlib=sasuser.userfuncs.mystring; 
FUNCTION count_rus_letters(string $); 
length letter $2; 

rus_count=0; 

len=klength(string); 

do i=1 to len; 
    letter=ksubstr(string,i,1); 
    if letter in ("А","а","Б","б","В","в","Г","г","Д","д","Е","е","Ё","ё","Ж","ж" 
     "З","з","И","и","Й","й","К","к","Л","л","М","м","Н","н","О","о","П","п","Р","р", 
     "С","с","Т","т","У","у","Ф","ф","Х","х","Ц","ц","Ч","ч","Ш","ш","Щ","щ","Ъ","ъ" 
     "Ы","ы","Ь","ь","Э","э","Ю","ю","Я","я") 
    then rus_count+1; 
end; 

return(rus_count); 
endsub; 
run; 

/**************************************************************************/ 
/* FUNCTION count_eng_letters RETURNS NUMBER OF ENGLISH LETTERS IN STRING */ 
/**************************************************************************/ 
proc fcmp outlib=sasuser.userfuncs.mystring; 
FUNCTION count_eng_letters(string $); 
length letter $2; 

eng_count=0; 

len=klength(string); 

do i=1 to len; 
    letter=ksubstr(string,i,1); 
    if rank('A') <= rank(letter) <=rank('z') 
    then eng_count+1; 
end; 

return(eng_count); 
endsub; 
run; 

/**************************************************************************/ 
/* FUNCTION is_string_russian RETURNS 1 IF NUMBER OF RUSSIAN SYMBOLS IN */ 
/* STRING >= NUMBER OF ENGLISH SYMBOLS         */ 
/**************************************************************************/ 
proc fcmp outlib=sasuser.userfuncs.mystring; 
FUNCTION is_string_russian(string $); 
length letter $2 result 8; 

eng_count=0; 
rus_count=0; 

len=klength(string); 

do i=1 to len; 
    letter=ksubstr(string,i,1); 
    if letter in ("А","а","Б","б","В","в","Г","г","Д","д","Е","е","Ё","ё","Ж","ж" 
     "З","з","И","и","Й","й","К","к","Л","л","М","м","Н","н","О","о","П","п","Р","р", 
     "С","с","Т","т","У","у","Ф","ф","Х","х","Ц","ц","Ч","ч","Ш","ш","Щ","щ","Ъ","ъ" 
     "Ы","ы","Ь","ь","Э","э","Ю","ю","Я","я") 
    then rus_count+1; 
    if rank('A') <= rank(letter) <=rank('z') 
    then eng_count+1; 
end; 

if rus_count>=eng_count 
then result=1; 
else result=0; 

return(result); 
endsub; 
run; 

/**************************************************************************/ 
/* FUNCTION fix_layout_misprints REPLACES MISPRINTED SYMBOLS BY ANALYSING */ 
/* LANGUAGE OF THE STRING (FOR ENGLISH STRING RUSSIAN SYMBOLS ARE   */ 
/* REPLACED BY ENGLISH COPIES AND FOR RUSSIAN STRING SYMBOLS ARE   */ 
/* REPLACED BY RUSSIAN COPIES)           */ 
/**************************************************************************/ 
proc fcmp outlib=sasuser.userfuncs.mystring; 
FUNCTION fix_layout_misprints(string $) $ 1000; 
length letter $2 result $1000; 

eng_count=0; 
rus_count=0; 

len=klength(string); 

do i=1 to len; 
    letter=ksubstr(string,i,1); 
    if letter in ("А","а","Б","б","В","в","Г","г","Д","д","Е","е","Ё","ё","Ж","ж" 
     "З","з","И","и","Й","й","К","к","Л","л","М","м","Н","н","О","о","П","п","Р","р", 
     "С","с","Т","т","У","у","Ф","ф","Х","х","Ц","ц","Ч","ч","Ш","ш","Щ","щ","Ъ","ъ" 
     "Ы","ы","Ь","ь","Э","э","Ю","ю","Я","я") 
    then rus_count+1; 
    if rank('A') <= rank(letter) <=rank('z') 
    then eng_count+1; 
end; 

if rus_count>=eng_count 
then result=ktranslate(string,"АаВЕеКкМОоРрСсТХх","AaBEeKkMOoPpCcTXx"); 
else result=ktranslate(string,"AaBEeKkMOoPpCcTXx","АаВЕеКкМОоРрСсТХх"); 

return(result); 
endsub; 
run; 

/***********/ 
/* EXAMPLE */ 
/***********/ 
options cmplib=sasuser.userfuncs; 
data _null_; 
good_str="Иванов"; 
err_str="Ивaнов"; 
fixed_str=fix_layout_misprints(err_str); 

put "Good string=" good_str; 
put "Error string=" err_str; 
put "Fixed string=" fixed_str; 

rus_count_in_err=count_rus_letters(err_str); 
put "Count or Cyrillic symbols in error string=" rus_count_in_err; 

eng_count_in_err=count_eng_letters(err_str); 
put "Count or English symbols in error string=" eng_count_in_err; 

is_error_str_russian=is_string_russian(err_str); 
put "Is error string language Russian=" is_error_str_russian; 

if (good_str ne err_str) 
then put "Before clearing - strings are not equal to each other"; 

if (good_str = fixed_str) 
then put "After clearing - strings are equal to each other"; 
run;