使用 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));

请注意,这还将消除通过替换多个单字节字符而生成的多个相邻下划线。所以它还有一个额外的优势,就是让那些生成的名字也更容易处理。