英文:
Is there a way to edit values in list after %let in SAS
问题
我创建了一个宏变量:%let hi = ('g', 'c', 'v', 'd'); 我想将这个列表放入代码中,但需要为每个值添加%%,看起来像这样('%g%', '%c%', '%v%', '%d%')。有办法得到这个结果吗?
我想要%%,因为我想在 SQL 中使用 LIKE。
英文:
I created a macro variable: %let hi = ('g', 'c', 'v', 'd'); I
want to put this list in code but need to add %% for each value, looks like this('%g%', '%c%', '%v%', '%d%'). is there a way i can get the result?
I want to have %% because I want to use LIKE in sql.
答案1
得分: 1
我假设您的列表可能包含一个或多个单词,因此您可以使用正则表达式进行更改。模式是懒惰地查找由单引号括起的任何文本,并将其替换为'%...%'
。
PRXCHANGE
执行正则表达式替换。第一个参数是正则表达式模式。下一个参数-1
表示对每个找到的匹配执行更改。
%let hi = ('word1 word2', ' word3 word4 ');
data _null_;
hi = prxchange("s/'(.*?)'/'%$1%'/", -1, "&hi");
call symputx('hi', hi);
run;
%put &=hi;
HI=('%word1 word2%', '% word3 word4 %')
替换的正则表达式遵循s/模式/替换/
的一般结构。在这种情况下,模式是查找文本及其封闭的单引号。用于这一目的的简单模式是'.*'
。.
表示任何单个字符,*
是一个修饰符,表示任意数量或没有。模式中添加的问号?
创建了懒惰匹配,这意味着匹配最短可能的字符串。默认情况下,正则表达式匹配是贪婪的,意味着匹配最长可能的字符串,但在这种情况下会导致问题,因为我们的宏变量中有多个单引号。模式中的括号()
创建了一个捕获组,它将匹配文本保存在括号内的缓冲区中,可以在替换中引用。
正则表达式替换的替代部分'%$1%'
是指$1
。这是在搜索模式中由括号创建的捕获组中的文本。匹配的文本将用百分号括起,然后用单引号括起。就这样。
英文:
I assume that your list may have one or more words, so you can use regex to make the change. The pattern is to lazily find any text surrounded by single quotes and replace it with '%...%'
.
PRXCHANGE
performs a regex substitution. The first parameter is the regex pattern. The next parameter -1
means to perform the change for every match found.
%let hi = ('word1 word2', ' word3 word4 ');
data _null_;
hi = prxchange("s/'(.*?)'/'%$1%'/", -1, "&hi");
call symputx('hi', hi);
run;
%put &=hi;
HI=('%word1 word2%', '% word3 word4 %')
The regex for substitution follows the general structure of s/Pattern/Replacement/
. The pattern in this case is to find text and its enclosing single quotes. The simple pattern for that is '.*'
. The .
means any single character, and the *
is a modifier which means any number or none at all. The question mark ?
added to the pattern creates a lazy match which means to match the shortest possible string. By default, regex matches are greedy meaning to match the longest possible string, but that causes problems in this case because we have multiple single quotes in our macro var. The parentheses ()
in the pattern creates a capture group which saves the matching text within the parentheses to a buffer which can be referred to in the replacement.
The replacement part of the regex substitution '%$1%'
refers to $1
. It is the text in the capture buffer created by the parentheses in the search pattern. That matching text will be wrapped with percents then single quotes. Voila.
答案2
得分: 0
最直接的方法是循环遍历列表中的项目并构建一个新列表。在宏代码中处理百分号和逗号会比较麻烦,所以也许在数据步骤中做这个会容易得多。
示例:
%let list=('a','b','c');
data _null_;
length old new word $1000 ;
old=symget('list');
do i=1 to countw(old,'( ,)','q');
word=quote(cats('%',dequote(scan(old,i,'( ,)','q')),'%'),"'");
new=catx(',',new,word);
end;
call symputx('newlist',cats('(',new,')'));
run;
%put &newlist;
结果
379 %put &newlist;
('%a%','%b%','%c%')
请注意,在数据步骤中,宏变量的长度可以比字符变量长。变量的最大长度为32K(32,767),而宏变量为64K。
英文:
The most straight forward way would be loop over the items in the list and build a new list. Dealing with % and commas is a pain in macro code. So perhaps it would be a lot easier to just do it in a data step.
Example;
%let list=('a','b','c');
data _null_;
length old new word $1000 ;
old=symget('list');
do i=1 to countw(old,'( ,)','q');
word=quote(cats('%',dequote(scan(old,i,'( ,)','q')),'%'),"'");
new=catx(',',new,word);
end;
call symputx('newlist',cats('(',new,')'));
run;
%put &newlist;
Result
379 %put &newlist;
('%a%','%b%','%c%')
Note that a macro variable can be longer than a character variable in a data step. The maximum length in a variable is 32K (32,767) versus 64K for a macro variable.
答案3
得分: 0
%nrstr()
函数可以屏蔽特殊字符,防止宏系统陷入困境。
一开始,你可以这样赋值:
%let hi = %nrstr(%( '%g%' , '%c%' , '%v%' , '%d%' %));
%put NOTE: hi = %superq(hi);
----- Log -----
NOTE: hi = ( '%g%' , '%c%' , '%v%' , '%d%' )
英文:
%nrstr()
masks special characters and prevents the macro system from going down a rabbit hole.
At the outset you can make the assignment as follows:
%let hi = %nrstr(%( '%g%' , '%c%' , '%v%' , '%d%' %));
%put NOTE: hi = %superq(hi);
----- Log -----
NOTE: hi = ( '%g%' , '%c%' , '%v%' , '%d%' )
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论