Proc FCMP 기능이 항상 33 바이트 이상을 반환하는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1032238

  •  06-07-2019
  •  | 
  •  

문제

Proc FCMP를 통해 다음과 같은 기능이 정의되어 있습니다. 코드의 요점은 매우 명백하고 비교적 간단해야합니다. XHTML 라인에서 속성 값을 반환하고 있습니다. 코드는 다음과 같습니다.

proc fcmp outlib=library.funcs.crawl;
    function getAttr(htmline $, Attribute $) $;

       /*-- Find the position of the match --*/
    Pos = index( htmline , strip( Attribute )||"=" );

       /*-- Now do something about it --*/
       if pos > 0 then do;
          Value = scan( substr( htmline, Pos + length( Attribute ) + 2), 1, '"');
       end;
       else Value = "";
       return( Value);
    endsub;
run;

길이 또는 attrib 문으로 무엇을하는지에 관계없이 데이터 유형을 명시 적으로 선언하려고 시도하더라도 실제 반환 값의 시간에 관계없이 항상 요청 된 문자열의 최대 33 바이트 만 반환합니다. 이것은 내가 검색하는 속성에 관계없이 발생합니다. 데이터 단계에 동일한 코드 (하드 코딩)가 올바른 결과를 리턴하므로 Proc FCMP와 관련이 있습니다.

다음은 테스트하는 데 사용하는 데이터 스타입니다 (Pagesource.html은 xhtml 호환 속성이있는 HTML 파일입니다.

data TEST;
length href $200;
infile "F:\PageSource.html";

input;

htmline = _INFILE_;

href = getAttr( htmline, "href");
x = length(href);

run;

업데이트 : SAS9.2로 업그레이드 한 후 제대로 작동하는 것 같습니다.

도움이 되었습니까?

해결책 3

FCMP 정의 데이터 단계 기능을 사용하여 백업되었습니다. 나는 그들이 프라임 타임에 대한 준비가되어 있다고 생각하지 않습니다. 33 바이트 반환 문제를 해결할 수있을뿐만 아니라 SAS가 정기적으로 충돌하기 시작했습니다.

따라서 매크로의 좋은 오래된 (수십 년 된) 기술로 돌아갑니다. 이것은 작동합니다 :

/*********************************/
/*= Macro to extract Attribute  =*/
/*= from XHTML string           =*/
/*********************************/
%macro getAttr( htmline, Attribute, NewVar );
   if index( &htmline , strip( &Attribute )||"=" ) > 0 then do;
      &NewVar = scan( substr( &htmline, index( &htmline , strip( &Attribute )||"=" ) + length( &Attribute ) + 2), 1, '"' );
   end;
%mend;

다른 팁

이 경우 입력 포인터 컨트롤로 충분해야합니다. 도움이 되었기를 바랍니다.

/* create a test input file */
data _null_;
  file "f:\pageSource.html";
  input;
  put _infile_;
cards4;
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="w3.org/StyleSheets/TR/W3C-REC.css"; type="text/css"?>
;;;;
run;

/* extract the href attribute value, if any.                          */
/* assuming that the value and the attribute name occurs in one line. */
/* and max length is 200 chars.                                       */
data one;
  infile "f:\pageSource.html" missover;
  input @("href=") href :$200.;
  href = scan(href, 1, '"'); /* unquote */
run;

/* check */
proc print data=one;
run;
/* on lst
Obs                  href
 1
 2     w3.org/StyleSheets/TR/W3C-REC.css
*/

문제가 스캔 함수에 있다고 생각합니다. substr ()에서 입력을 자르는 것 같습니다. scan ()에서 substr 함수를 끌어 내면 substr 함수의 결과를 새로운 변수에 할당 한 다음 스캔하기 위해 전달하면 작동하는 것 같습니다.

여기에 내가 실행 한 내용은 다음과 같습니다.

proc fcmp outlib=work.funcs.crawl;
    function getAttr(htmline $, Attribute $) $;
    length y $200;
       /*-- Find the position of the match --*/
    Pos = index( htmline , strip( Attribute )||"=" );

       /*-- Now do something about it --*/
       if pos > 0 then do;
          y=substr( htmline, Pos + length( Attribute ) + 2);
          Value = scan( y, 1, '"');       
       end;
       else Value = "";
       return( Value);
    endsub;
run;

options cmplib=work.funcs;

data TEST;
length href $200;
infile "PageSource.html";

input;

htmline = _INFILE_;
href = getAttr( htmline, "href");
x = length(href);
run;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top