在我看来,将prxmatch与SAS DS2一起使用时出现错误。我的代码也有可能出错。我想知道这个问题是因为我的代码还是SAS的编译错误。
在下面的代码中,我将一个数据表中的搜索词与另一个数据表中的搜索词进行匹配。
data master_table;
input name $ search_text $;
datalines;
Frank allHere
John Sales
Mary Acctng
Joe Findme
Sue Hereiam
Jim graccaa
;
run;
proc print data= master_table; run;
data search_term_table;
infile datalines missover;
input id $ search_term $;
datalines;
1 Here
2 Find
3 Acc
;
run;
proc ds2;
data search_results (overwrite=yes);
retain rc;
dcl double rc c ;
declare char(8) id N;
declare char(11) name;
declare char(1) c_options;
declare char(20) search_term search_text;
dcl package hash h(1, 'search_term_table');
dcl package hiter hi('h');
method init();
rc = h.keys([id]);
rc = h.data([id search_term]);
rc = h.defineDone();
end;
method run();
dcl double rc;
set master_table;
if _N_ = 1 then put 'ROW ITEM';
N = _N_;
rc = hi.first();
do while(rc=0);
c_options = 'i';
search_term = cats('/', search_term, '/', c_options);
search_text = catx(' ', search_text);
c = prxmatch(search_term, search_text);
put N id 'prxmatch(' search_term ',' search_text '); ---> ' c;
output;
rc = hi.next();
end;
end;
enddata;
run;
quit;
put语句的结果如下所示。
在ROW 3
ITEM 1
中找不到匹配项,因为它使用的是前一行最后一项而不是当前项的正则表达式。
在ROW 5
ITEM 1
中,情况相反。找不到匹配项,因为它再次使用了上一行最后一项中的正则表达式。
ROW ITEM
1 1 prxmatch( /Here/i , allHere ); ---> 4
1 2 prxmatch( /Find/i , allHere ); ---> 0
1 3 prxmatch( /Acc/i , allHere ); ---> 0
2 1 prxmatch( /Here/i , Sales ); ---> 0
2 2 prxmatch( /Find/i , Sales ); ---> 0
2 3 prxmatch( /Acc/i , Sales ); ---> 0
3 1 prxmatch( /Here/i , Acctng ); ---> 1
3 2 prxmatch( /Find/i , Acctng ); ---> 0
3 3 prxmatch( /Acc/i , Acctng ); ---> 1
4 1 prxmatch( /Here/i , Findme ); ---> 0
4 2 prxmatch( /Find/i , Findme ); ---> 1
4 3 prxmatch( /Acc/i , Findme ); ---> 0
5 1 prxmatch( /Here/i , Hereiam ); ---> 0
5 2 prxmatch( /Find/i , Hereiam ); ---> 0
5 3 prxmatch( /Acc/i , Hereiam ); ---> 0
6 1 prxmatch( /Here/i , graccaa ); ---> 3
6 2 prxmatch( /Find/i , graccaa ); ---> 0
6 3 prxmatch( /Acc/i , graccaa ); ---> 3
NOTE: Execution succeeded. 18 rows affected.
2752 quit;
答案 0 :(得分:1)
PRXMATCH
可能正在使用隐式/o
进行一些奇怪的已编译正则表达式缓存。即使考虑到某些PRXMATCH模式可能已经“一次”编译,我也无法弄清楚观察到的输出背后的原理。
不幸的是,DS2不喜欢CALL PRXDEBUG(1);
,它可能会带来一些启发。
编译Perl正则表达式
如果perl-regular-expression是常数或使用/ o选项,则Perl正则表达式将被编译一次,并且每次使用PRXMATCH都会重新使用编译后的表达式。如果perl-regular-expression不是常数,并且不使用/ o选项,则将为每次对PRXMATCH的调用重新编译Perl正则表达式。
注意:当您在DATA步骤,WHERE子句或PROC SQL中使用PRXMATCH时,就会发生一次编译行为。对于所有其他用途,每次调用PRXMATCH都会重新编译perl-regular-expression。
因此,文档并没有完全阐明DS2中发生的情况,但是您知道有时会发生一些特殊情况。
最好的 fix 是显式PRXPARSE动态正则表达式模式以获得在PRXMATCH中使用的ID
dcl int rx;
rx = prxparse(search_term);
c = prxmatch(rx, search_text);
这可能是内存问题,因为没有PRXFREE
函数并且DS2不允许使用调用例程CALL PRXFREE(rx);
为避免潜在的“内存”问题,请创建prxparsed ID的数组或哈希将使用的模式,以及使用通过search_term查找获取的ID的模式。