带有 m 修饰符的扫描功能无法按预期工作

问题描述

扫描功能似乎无法如我所愿。

UPDATE tournament_matches
SET match_id = 5
WHERE team_name IN (
    SELECT IF(winner = 'team1',team1_name,team2_name)
    FROM get5_stats_matches
    WHERE match_id = 1);

结果:

enter image description here

它适用于 i=2 但我不明白为什么 i=3 和 i=4 是空白的... 我想要的是 scan=blank 只有 i=2 有连续分隔符。

但是,如果我的分隔符是逗号,它就可以工作...

data test;
do i=1 to 5;
text="ABC¤¤ABC¤ABC¤ABC";
scan = scan(text,i,"¤","m");
output;
end;
run;

结果:

enter image description here

我做错了什么???

解决方法

为了更详细地了解 Tom 的(正确)答案,SAS 是一种早在 Unicode 出现之前就存在的语言。它在很大程度上保持了向后兼容性,这意味着许多 SAS 函数与 Unicode 不兼容。

SAS 有一个页面 Internationalization Compatibility with SAS String functions,其中详细介绍了哪些函数与非单字节字符集(例如,UTF-8,多字节字符集)兼容。

列为“I18N Level 0”(I18N 是 Internationalization 的缩写 - I 和最后 n 之间的 18 个字符)的函数与非单字节字符集不兼容。 SCAN 是这些功能之一。 “I18N 1 级”可能有效,也可能无效,“I18N 2 级”旨在与 MBCS(如 UTF-8)配合使用。

在大多数情况下,考虑到 UTF-8 设计的函数以“k”开头,其他方面与基本 SAS 函数类似。但是,在少数情况下,他们不得不进行变体。

供您使用,kscanx 是您需要的函数。这允许使用 m 修饰符。

如果您的 SAS 会话和您的 SAS 数据不是完全相同的编码,您仍然可能会遇到问题。考虑使用 UNICODEUNICODEC 函数或 KCVT 函数来修改一个或另一个的字符集以匹配。

,

您的 SAS 会话正在使用 unicode。因此,您尝试使用的符号需要一个以上的字节。 SCAN() 函数会将其视为两个单独的分隔符。因此,M 修饰符将看到相邻的两个不同字节表示缺失值。

改用 KSCAN() 函数。

要使用 M 修饰符,您需要使用 KSCANX() 函数。 (我已经要求 SAS 更新这三个函数的文档,以便它们相互引用。)

您可以尝试用一些单字节字符替换两字节字符,以便您可以使用 SCAN() 函数,但是您也可能会遇到将分隔符视为其他多字节中的字节之一的问题字符串中的字符。

,

我运行了程序

data test;
do i=1 to 5;
text="ABC¤¤ABC¤ABC¤ABC";
scan = scan(text,i,"¤","m");
output;
end;
run;

得到这个

enter image description here