将 prxmatch 与 DS2 一起使用时出现 SAS 错误
SAS error using prxmatch with DS2
在我看来,将 prxmatch 与 SAS DS2 一起使用时出现错误。也有可能是我的代码有误。我想知道这个问题是因为我的代码还是 SAS 的编译错误。
在下面的代码中,我将一个数据 table 中的搜索词与另一个数据中的搜索文本进行匹配。
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;
PRXMATCH
可能正在使用隐式 /o
进行一些奇怪的已编译正则表达式缓存。我无法弄清楚观察到的输出背后的基本原理,即使考虑到某些 PRXMATCH 模式可能已经编译 'once'.
不幸的是,DS2 不喜欢 CALL PRXDEBUG(1);
这可能已经说明了一些问题。
Compiling a Perl Regular Expression
If perl-regular-expression is a constant or if it uses the /o option, then the Perl regular expression is compiled once and each use of PRXMATCH reuses the compiled expression. If perl-regular-expression is not a constant and if it does not use the /o option, then the Perl regular expression is recompiled for each call to PRXMATCH.
Note: The compile-once behavior occurs when you use PRXMATCH in a DATA step, in a WHERE clause, or in PROC SQL. For all other uses, the perl-regular-expression is recompiled for each call to PRXMATCH.
所以文档并没有完全说明 DS2 中发生了什么,但你知道有时会发生一些特别的事情。
最好的修复 是明确地 PRXPARSE 动态正则表达式模式以获得在 PRXMATCH
中使用的 id
dcl int rx;
rx = prxparse(search_term);
c = prxmatch(rx, search_text);
这可能是内存问题,因为没有 PRXFREE
函数并且 DS2 不允许使用调用例程 CALL PRXFREE(rx);
为避免潜在的“内存”问题,请创建一个数组或 ID 散列将使用的 prxparsed 模式,并使用通过 search_term 查找检索到的 ID。
在我看来,将 prxmatch 与 SAS DS2 一起使用时出现错误。也有可能是我的代码有误。我想知道这个问题是因为我的代码还是 SAS 的编译错误。
在下面的代码中,我将一个数据 table 中的搜索词与另一个数据中的搜索文本进行匹配。
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;
PRXMATCH
可能正在使用隐式 /o
进行一些奇怪的已编译正则表达式缓存。我无法弄清楚观察到的输出背后的基本原理,即使考虑到某些 PRXMATCH 模式可能已经编译 'once'.
不幸的是,DS2 不喜欢 CALL PRXDEBUG(1);
这可能已经说明了一些问题。
Compiling a Perl Regular Expression
If perl-regular-expression is a constant or if it uses the /o option, then the Perl regular expression is compiled once and each use of PRXMATCH reuses the compiled expression. If perl-regular-expression is not a constant and if it does not use the /o option, then the Perl regular expression is recompiled for each call to PRXMATCH.
Note: The compile-once behavior occurs when you use PRXMATCH in a DATA step, in a WHERE clause, or in PROC SQL. For all other uses, the perl-regular-expression is recompiled for each call to PRXMATCH.
所以文档并没有完全说明 DS2 中发生了什么,但你知道有时会发生一些特别的事情。
最好的修复 是明确地 PRXPARSE 动态正则表达式模式以获得在 PRXMATCH
中使用的 id dcl int rx;
rx = prxparse(search_term);
c = prxmatch(rx, search_text);
这可能是内存问题,因为没有 PRXFREE
函数并且 DS2 不允许使用调用例程 CALL PRXFREE(rx);
为避免潜在的“内存”问题,请创建一个数组或 ID 散列将使用的 prxparsed 模式,并使用通过 search_term 查找检索到的 ID。