用英文字符替换土耳其字符
Replacing Turkish characters with English characters
我有一个 table,它有 120 列,其中一些包含土耳其语字符(例如“ç”、“ğ”、“ı”、“ö”)。所以我想用英文字符替换这个土耳其字符(例如 "c"、"g"、"i"、"o")。当我使用 "TRANWRD Function" 时,它可能真的很难,因为我应该编写函数 120 次,有时 hte 列名称可能会更改,因此我总是必须一一检查代码。
是否有一个简单的宏来替换所有列中的这些字符。
首先从字典中获取所有列,然后在宏 do 循环中替换所有列的值。
您可以尝试这样的程序(将 MYTABLE 替换为您的 table 名称):
proc sql;
select name , count(*) into :columns separated by ' ', :count
from dictionary.columns
where memname = 'MYTABLE';
quit;
%macro m;
data mytable;
set mytable;
%do i=1 %to &count;
%scan(&columns ,&i) = tranwrd(%scan(&columns ,&i),"ç","c");
%scan(&columns ,&i) = tranwrd(%scan(&columns ,&i),"ğ","g");
...
%end;
%mend;
%m;
编辑
回想起来,这是一个过于复杂的解决方案......应该使用 translate()
功能,正如另一位用户所指出的那样。当重复使用时,它可以集成到用 PROC FCMP
定义的 SAS 函数中。
正则表达式和 DO 循环的组合可以实现这一点。
第 1 步:按以下方式构建转化table
解析为相同替换字符的重音字母放在一行中,由 | 分隔符号.
data conversions;
infile datalines dsd;
input orig $ repl $;
datalines;
ç,c
ğ,g
ı,l
ö|ò|ó,o
ë|è,e
;
步骤 2:将原始字符串和替换字符串存储在宏变量中
proc sql noprint;
select orig, repl, count(*)
into :orig separated by ";",
:repl separated by ";",
:nrepl
from conversions;
quit;
第 3 步:进行实际转换
为了展示它是如何工作的,我们只处理一列。
data convert(drop=i re);
myString = "ç ğı òö ë, è";
do i = 1 to &nrepl;
re = prxparse("s/" || scan("&orig",i,";") || "/" || scan("&repl",i,";") || "/");
myString = prxchange(re,-1,myString);
end;
run;
结果 myString
:"c gl oo e, e"
为了处理所有字符列,我们使用数组
假设您的 table 被命名为 mySource
并且您希望处理所有字符变量;我们将为此创建一个名为 cols
的向量。
data convert(drop=i re);
set mySource;
array cols(*) _character_;
do c = 1 to dim(cols);
do i = 1 to &nrepl;
re = prxparse("s/" || scan("&orig",i,";") || "/" || scan("&repl",i,";") || "/");
cols(c) = prxchange(re,-1,cols(c));
end;
end;
run;
当更改单个字符 TRANSLATE 是正确的功能时,这将是一行代码。
translated = translate(string,"cgio","çğıö");
我有一个 table,它有 120 列,其中一些包含土耳其语字符(例如“ç”、“ğ”、“ı”、“ö”)。所以我想用英文字符替换这个土耳其字符(例如 "c"、"g"、"i"、"o")。当我使用 "TRANWRD Function" 时,它可能真的很难,因为我应该编写函数 120 次,有时 hte 列名称可能会更改,因此我总是必须一一检查代码。
是否有一个简单的宏来替换所有列中的这些字符。
首先从字典中获取所有列,然后在宏 do 循环中替换所有列的值。
您可以尝试这样的程序(将 MYTABLE 替换为您的 table 名称):
proc sql;
select name , count(*) into :columns separated by ' ', :count
from dictionary.columns
where memname = 'MYTABLE';
quit;
%macro m;
data mytable;
set mytable;
%do i=1 %to &count;
%scan(&columns ,&i) = tranwrd(%scan(&columns ,&i),"ç","c");
%scan(&columns ,&i) = tranwrd(%scan(&columns ,&i),"ğ","g");
...
%end;
%mend;
%m;
编辑
回想起来,这是一个过于复杂的解决方案......应该使用 translate()
功能,正如另一位用户所指出的那样。当重复使用时,它可以集成到用 PROC FCMP
定义的 SAS 函数中。
正则表达式和 DO 循环的组合可以实现这一点。
第 1 步:按以下方式构建转化table
解析为相同替换字符的重音字母放在一行中,由 | 分隔符号.
data conversions;
infile datalines dsd;
input orig $ repl $;
datalines;
ç,c
ğ,g
ı,l
ö|ò|ó,o
ë|è,e
;
步骤 2:将原始字符串和替换字符串存储在宏变量中
proc sql noprint;
select orig, repl, count(*)
into :orig separated by ";",
:repl separated by ";",
:nrepl
from conversions;
quit;
第 3 步:进行实际转换
为了展示它是如何工作的,我们只处理一列。
data convert(drop=i re);
myString = "ç ğı òö ë, è";
do i = 1 to &nrepl;
re = prxparse("s/" || scan("&orig",i,";") || "/" || scan("&repl",i,";") || "/");
myString = prxchange(re,-1,myString);
end;
run;
结果 myString
:"c gl oo e, e"
为了处理所有字符列,我们使用数组
假设您的 table 被命名为 mySource
并且您希望处理所有字符变量;我们将为此创建一个名为 cols
的向量。
data convert(drop=i re);
set mySource;
array cols(*) _character_;
do c = 1 to dim(cols);
do i = 1 to &nrepl;
re = prxparse("s/" || scan("&orig",i,";") || "/" || scan("&repl",i,";") || "/");
cols(c) = prxchange(re,-1,cols(c));
end;
end;
run;
当更改单个字符 TRANSLATE 是正确的功能时,这将是一行代码。
translated = translate(string,"cgio","çğıö");