如何在SAS中拆分无分隔符的字符串为指定5个变量?
SAS无分隔符混合字符串拆分方法
针对给定的SAS数据集,每条观测是由姓名(字母)、年龄(数字)、性别(字母)、体重(数字)、国家(字母)组成的无分隔符混合字符串,以下是几种实用拆分方法:
方法1:正则表达式捕获组提取
利用正则表达式的捕获组匹配固定模式的字符串,精准提取各字段:
data want; set have; retain re; /* 编译正则:匹配字母(姓名)+数字(年龄)+字母(性别)+数字(体重)+字母(国家)的模式 */ if _n_ = 1 then re = prxparse('/^([A-Za-z]+)(\d+)([A-Za-z]+)(\d+)([A-Za-z]+)$/'); /* 提取姓名 */ call prxposn(re, 1, start, length); Name = substr(string, start, length); /* 提取年龄并转数值 */ call prxposn(re, 2, start, length); Age = input(substr(string, start, length), 8.); /* 提取性别 */ call prxposn(re, 3, start, length); Gender = substr(string, start, length); /* 提取体重并转数值 */ call prxposn(re, 4, start, length); Weight = input(substr(string, start, length), 8.); /* 提取国家 */ call prxposn(re, 5, start, length); Country = substr(string, start, length); drop re start length; run;
方法2:遍历字符类型拆分
逐个判断字符是字母还是数字,根据字段类型切换提取逻辑,适合模式有变化的场景:
data want; set have; length Name Gender Country $20; Age Weight 8.; /* 初始化变量 */ Name = ''; Age = .; Gender = ''; Weight = .; Country = ''; current_step = 1; /* 1=提取姓名(字母), 2=提取年龄(数字), 3=提取性别(字母), 4=提取体重(数字), 5=提取国家(字母) */ char_buf = ''; num_buf = ''; do i = 1 to length(string); curr_char = substr(string, i, 1); if current_step in (1,3,5) then do; /* 当前提取字母字段 */ if not digit(curr_char) then do; char_buf = catx('', char_buf, curr_char); end; else do; /* 遇到数字,切换到数字字段处理 */ select(current_step); when(1) Name = char_buf; when(3) Gender = char_buf; end; char_buf = ''; num_buf = catx('', num_buf, curr_char); current_step + 1; end; end; else if current_step in (2,4) then do; /* 当前提取数字字段 */ if digit(curr_char) then do; num_buf = catx('', num_buf, curr_char); end; else do; /* 遇到字母,切换到字母字段处理 */ select(current_step); when(2) Age = input(num_buf, 8.); when(4) Weight = input(num_buf, 8.); end; num_buf = ''; char_buf = catx('', char_buf, curr_char); current_step + 1; end; end; end; /* 处理最后一段国家字段 */ if current_step = 5 then Country = char_buf; drop i curr_char current_step char_buf num_buf; run;
方法3:利用固定性别字符串定位拆分
如果性别只有Male/Female两种固定值,可以先定位性别位置,再拆分前后字段:
data want; set have; length Name Gender Country $20; Age Weight 8.; /* 定位性别位置和长度 */ if find(string, 'Female') then do; Gender = 'Female'; gender_pos = find(string, 'Female'); gender_len = 6; end; else if find(string, 'Male') then do; Gender = 'Male'; gender_pos = find(string, 'Male'); gender_len = 4; end; /* 拆分姓名和年龄:性别之前的部分 */ pre_gender = substr(string, 1, gender_pos - 1); age_start = length(pre_gender) - verify(reverse(pre_gender), '0123456789') + 2; Name = substr(pre_gender, 1, age_start - 1); Age = input(substr(pre_gender, age_start), 8.); /* 拆分体重和国家:性别之后的部分 */ post_gender = substr(string, gender_pos + gender_len); weight_end = verify(post_gender, '0123456789'); Weight = input(substr(post_gender, 1, weight_end - 1), 8.); Country = substr(post_gender, weight_end); drop pre_gender post_gender gender_pos gender_len age_start weight_end; run;
内容的提问来源于stack exchange,提问作者Anvesh Reddy
相关产品推荐
相关产品推荐

