使用 PXRCHANGE 时重音字符发生双重替换
Double replacement occurring for accented characters when using PXRCHANGE
我在使用 PXRCHANGE
将 ö
等重音字符替换为下划线时遇到问题。更准确地说,当我执行替换时,不是 ö
被单个下划线 _
替换,而是被两个下划线 __
替换。这不仅仅是 ö
的孤立实例,其他几个重音字符也会出现这种情况。
这里有一些虚拟代码来复制我的问题:
option validvarname = any;
data dummy_data;
input "ö"n "aü"n;
datalines;
1 1
2 2
;
run;
data badvarnames (keep = name validname);
set sashelp.vcolumn;
where libname = "WORK" and memname = "DUMMY_DATA";
validname = prxchange("s/[^a-zA-Z0-9]/_/", -1, trim(name));
name = nliteral(name);
run;
proc sql;
select cats("rename", name, "=", validname, ";") into : renamelist
separated by " " from badvarnames;
quit;
data output_tab;
set dummy_data;
&renamelist.;
run;
正则表达式函数将 multi-byte 个字符视为要替换的单个字节。因此,如果字符在 UTF-8 中使用两个字节,那么您会得到两个下划线。
这里有两个选择。
使用 KTRANSLATE() 处理 multi-byte 个字符。您可以使用 KCOMPRESS() 查找任何给定名称中的无效字符集。
valid = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
test2 = ktranslate(name,repeat('_',255),kcompress(name,valid));
或者通过将 +
添加到您的正则表达式,用单个下划线替换相邻的无效字符。
test3 = prxchange("s/[^a-zA-Z0-9]+/_/", -1, trim(name));
请注意,这还将消除通过替换多个单字节字符而生成的多个相邻下划线。所以它还有一个额外的优势,就是让那些生成的名字也更容易处理。
我在使用 PXRCHANGE
将 ö
等重音字符替换为下划线时遇到问题。更准确地说,当我执行替换时,不是 ö
被单个下划线 _
替换,而是被两个下划线 __
替换。这不仅仅是 ö
的孤立实例,其他几个重音字符也会出现这种情况。
这里有一些虚拟代码来复制我的问题:
option validvarname = any;
data dummy_data;
input "ö"n "aü"n;
datalines;
1 1
2 2
;
run;
data badvarnames (keep = name validname);
set sashelp.vcolumn;
where libname = "WORK" and memname = "DUMMY_DATA";
validname = prxchange("s/[^a-zA-Z0-9]/_/", -1, trim(name));
name = nliteral(name);
run;
proc sql;
select cats("rename", name, "=", validname, ";") into : renamelist
separated by " " from badvarnames;
quit;
data output_tab;
set dummy_data;
&renamelist.;
run;
正则表达式函数将 multi-byte 个字符视为要替换的单个字节。因此,如果字符在 UTF-8 中使用两个字节,那么您会得到两个下划线。
这里有两个选择。
使用 KTRANSLATE() 处理 multi-byte 个字符。您可以使用 KCOMPRESS() 查找任何给定名称中的无效字符集。
valid = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
test2 = ktranslate(name,repeat('_',255),kcompress(name,valid));
或者通过将 +
添加到您的正则表达式,用单个下划线替换相邻的无效字符。
test3 = prxchange("s/[^a-zA-Z0-9]+/_/", -1, trim(name));
请注意,这还将消除通过替换多个单字节字符而生成的多个相邻下划线。所以它还有一个额外的优势,就是让那些生成的名字也更容易处理。