假设我们有一个宏变量:
%let letters = a b c d e f g h i j;
首先,我要从宏变量中删除最后一个字母,并将剩下的字母分配给一个新的宏变量。其次,我希望从宏变量中删除任何给定的字母,并将剩余的字母分配给一个新的宏变量。我已经编写了两个宏来做这些事情,但是我想知道是否有更好的方法来处理它们。大多数其他编程语言都有这种类型的添加/删除函数,但是SAS似乎不-这是准确的吗?
第一个宏:
%macro remove_last_letter(macro_var);
%let letters_no_last = ;
%do i = 1 %to %sysfunc(countw(&&¯o_var..))-1;
%let this_letter = %scan(&&¯o_var.., &i.);
%let letters_no_last = &letters_no_last. &this_letter.;
%end;
%put &letters_no_last.;
%mend remove_last_letter;
%remove_last_letter(letters);
产量:
A b、c、d、f、g、h、i
第二个宏:
%macro remove_a_letter(macro_var, letter_to_remove);
%let letters_no_spec = ;
%do i = 1 %to %sysfunc(countw(&&¯o_var..));
%let this_letter = %scan(&&¯o_var.., &i.);
%if &this_letter. ~= &letter_to_remove. %then %do;
%let letters_no_spec = &letters_no_spec. &this_letter.;
%end;
%end;
%put &letters_no_spec.;
%mend remove_a_letter;
%remove_a_letter(letters, c);
产量:
A b d f g h i j
发布于 2016-05-24 20:56:10
SAS宏语言实际上不是一种功能齐全的语言。因此,不,它并不是为了存储我们在现代使用它的方式而设计的。我并不认为其他语言有专门的函数从字符串中删除特定的单词,这就是这里所拥有的;但是在SAS中,这并不特别困难。
第一个我认为,如果你使用的是单个字母,这是微不足道的。
%macro remove_last_letter(macro_var);
%put %substr(¯o_var.,1,%length(¯o_var.)-1);
%mend remove_last_letter;
当然,如果超过一个字符的长度,您当然需要知道最后一个字符的长度,但是您可以使用%sysfunc(countw())
来识别这个单词并找出它的长度--或者您可以在字符串中找到最后一个空格并使用它删除它,这可能更容易:
%macro remove_last_word(macro_var);
%let lastspacepos = %sysfunc(find(¯o_var.,%str( ),1-%length(¯o_var.)));
%put &=lastspacepos.;
%put %substr(¯o_var.,1,&lastspacepos.);
%mend remove_last_word;
%remove_last_word(abc def ghi jkl mno);
至于你的第二部分,我认为TRANWRD是该走的路。
%macro remove_a_letter(macro_var, letter_to_remove);
%put %sysfunc(tranwrd(¯o_var.,%str( )&letter_to_remove%str( ),%str( )));
%mend remove_a_letter;
%remove_a_letter(a b c d e f g h i j,c);
当然,它将删除字符串中的每个c
,而不仅仅是一个,但似乎您希望通过您的规范来实现这一点。
TRANWRD解决方案也可以用于第一个版本,方法是使用具有-1参数的扫描来抓取单词(最右边的单词),然后将TRANWRD用于空白,如果您知道它是一个独特的字符的话。
发布于 2016-05-24 21:09:06
看来你想删除单词而不是字母。此外,如果对宏进行编码,使它们可以作为宏函数工作,则宏可能会更有用。
要删除最后一个单词,你只需要知道它有多长。如果列表中没有至少两个单词,则不需要返回任何内容。
%macro remove_last_word(list);
%if %sysfunc(countw(&list,%str( ))) > 1 %then
%substr(&list,1,%length(&list)-%length(%scan(&list,-1,%str( ))))
;
%mend remove_last_word;
%put %remove_last_word(a b c d);
如果您想删除所有出现的单词,那么TRANWRD()
函数对此很好。确保将前导和尾随分隔符添加到列表和单词中,使其不匹配列表中较长单词的一部分。
%macro remove_word(list,word);
%sysfunc(tranwrd(%bquote( &list ),%bquote( &word ),%str( )))
%mend remove_word;
%put %remove_word(a b c d,c);
https://stackoverflow.com/questions/37423085
复制相似问题