英文:
Function to escape value before PRX function processing?
问题
我正在使用(大量)prx函数(Perl正则表达式函数),但在某些情况下,我会在宏函数中使用它们,并将某些内容作为参数传递进行搜索,例如:
%macro test(exp=);
proc sql noprint;
select file
into :_input_file trimmed
from folder_content
where prxmatch("/&exp.$/oi", strip(file))
;
quit;
%mend test
在大多数情况下,这种方法有效,但当exp
的值包含PRX元字符(例如/或括号)时除外。
良好的做法是转义这些字符,但这并不用户友好。比如说,如果我想搜索一个文件/home/user/file.txt
,斜杠会导致宏失败,而我应该传递值\/home\/user\/file.txt
。
在实现自己的转义函数之前,我想确保它是否已经存在,但我迄今为止还没有找到它。
我期望有一个原生的SAS函数可以将任何文本值转换为在PRX函数中“ready to use”的值。
英文:
I'm using (a lot) prx functions (Perl Regular eXpression functions), however in some cases, I use them within a macro function and pass something to search as a parameter, e.g.
%macro test(exp=);
proc sql noprint;
select file
into :_input_file trimmed
from folder_content
where prxmatch("/&exp.$/oi", strip(file))
;
quit;
%mend test
In most cases, this works, except when the value of exp
contains PRX metacharacter (e.g. / or parenthesis)
The good practice is to escape such characters, but that's not user friendly.
Let's say I want to search a file /home/user/file.txt
, the slashes will make cause the macro to fail, instead I should pass the value \/home\/user\/file.txt
Before implementing my own escaping function, I want to ensure it does not already exist, but I've not been able to find it so far
I expect a **native **SAS function to convert any text value into a "ready to use" value within a PRX function
答案1
得分: 1
The /
is an implicit m/
for matching. The first character after m
is the expression bounder. So, use an initial character such as #
. "#&exp.$#oi"
- any /
in the resolved &exp
will be treated as literal /
Mixing regex patterns with macro can be very frustrating and a seeming endless pit of escapism. Consider treating your patterns as data and join them to the data set of concern. Bonus is no macro.
rx = '....'; output;
rx = '....'; output;
...
run;
proc sql noprint;
create table matches as
select file
from folder_content
join mypatterns p
on prxmatch (strip(p.rx),strip(file))
;
quit;
英文:
The /
is an implicit m/
for matching. The first character after m
is the expression bounder. So, use an initial character such as #
. "#&exp.$#oi"
- any /
in the resolved &exp
will be treated as literal /
Mixing regex patterns with macro can be very frustrating and a seeming endless pit of escapism. Consider treating your patterns as data and join them to the data set of concern. Bonus is no macro.
data mypatterns;
rx = '....'; output;
rx = '....'; output;
...
run;
proc sql noprint;
create table matches as
select file
from folder_content
join mypatterns p
on prxmatch (strip(p.rx),strip(file))
;
quit;
答案2
得分: 1
以下是翻译好的内容:
没有像您请求的那样的函数(我甚至不确定我能理解这样一个函数应该做什么)。
但对于您只想将值视为字符串的示例(即不是实际的正则表达式),则没有太多需要发生的事情。
- 将任何现有的 \ 转换为 \\ 以防止它们被用于转义下一个字符。
- 在使用分隔符的任何出现位置(在您的示例中是 /)添加 \ 以进行转义。
所以如果您有名为 EXP 的宏变量
%let exp=c:\mixed_up/path ;
您可以将其转换为您可以在 WHERE 子句中使用的内容
%let want=%qsysfunc(tranwrd(%superq(exp),,\));
%let want=%qsysfunc(tranwrd(&want,/,/));
这将创建:
650 %put &=want;
WANT=c:\mixed_up/path
英文:
There is no function like you requested (I am not even sure I could understand what such a function would be expected to do).
But for your example of just wanting the treat the value as a STRING (ie not an actual regular expression) then there is not much that needs to happen.
- Convert any existing \ to \\ to prevent them from being used to escape the next character.
- Add \ to any occurrence of the separator you are using (in your example the /) to escape it.
So if you have macro variable named EXP
%let exp=c:\mixed_up/path ;
You can convert it to something you could use in your WHERE clause
%let want=%qsysfunc(tranwrd(%superq(exp),\,\\));
%let want=%qsysfunc(tranwrd(&want,/,\/));
Which will create:
650 %put &=want;
WANT=c:\\mixed_up\/path
答案3
得分: 0
Use something other than /
13 data null;
14 x = 'MCLAUREN';
15 x = prxchange("s!(MC)!\u\L$1!i", -1, x);
16 put x=;
17 x = prxchange("s/(MC)/\u\L$1/i", -1, x);
18 put x=;
19 run;
x=McLAUREN
x=McLAUREN
英文:
Use something other than /
13 data _null_;
14 x = 'MCLAUREN';
15 x = prxchange("s!(MC)!\u\L$1!i", -1, x);
16 put x=;
17 x = prxchange("s/(MC)/\u\L$1/i", -1, x);
18 put x=;
19 run;
x=McLAUREN
x=McLAUREN
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论