본문 바로가기
Programming/*Delphi

문자열 파싱 함수 (Pos / Copy 를 이용)

by Aur0ra 2018. 6. 18.

Copy 함수 
String 형의 문자 데이터에서 몇번째 자리 ~ 앞 Index 값에서 카운트 까지의 문자를 복사하여 값을 리턴해줍니다 .
(즉, 123456 이라는 데이터에서 1 Index 부터 4 count 라고 파라미터를 정해주었을때 리턴되는값은 1번째 문자자리인
'1' 부터 4자리뒤인 '4'까지, '1234'라는 데이터를 출력해줍니다)
파라미터 * 

Copy(S: <String or Dynamic Array>;Index : Integer; Count : Integer);



첫번째 S 에 오는 데이터는 복사할 문자의 전체 데이터입니다 .

가령

Delphi 라는 문자를 담은 변수가 있습니다 .

이문자에서 저는 'Del' 이라는 문자를 출력시키고싶습니다 .

그럼 복사할 문자의 전체데이터는 Delphi 를 담은 변수가 되겠죠 

var
A : String = 'Delphi';

그리고 D 는 1번째자리에 있으니 
Index 값은 1 로 줍니다 .

l 는 3번째 자리에 있으니 
count 값은 3 을 주고요 

var
 A : String = 'Delphi';
begin
 Result := Copy(A,1,3);
end;



실행시 리턴되는 값은 'Del' 인걸 확인하실수있습니다 .

이렇게 간단히 문자를 잘라올수있지만

원하는 문자부터 특정문자까지 잘라오는거엔 문제가있습니다.

그 데이터의 정확한 문자의 위치 를 알수가없습니다.


파싱이란

컴퓨터인터넷IT용어대사전

LR 파싱

[ LR parsing ]

상향식 파싱(buttom-upparsing) 기법의 하나. 컴파일러에서 주어진 문장의 문법적 구조를 분석하는 것. LR은 입력 스트링을 좌에서 우로 읽어가며 출력으로 우 파스(right parse)를 생성하기 때문에 이런 이름이 붙여졌다. bottom up 방식으로 구문을 분석한다. LR 파싱은 파싱 테이블의 구성 방법에 따라 SLR, CLR, LALR 방식으로 나눈다.

[네이버 지식백과] LR 파싱 [LR parsing] (컴퓨터인터넷IT용어대사전, 2011.1.20, 일진사)

컴퓨터인터넷IT용어대사전

LR 파싱[ LR parsing ]
상향식 파싱(buttom-upparsing) 기법의 하나. 
컴파일러에서 주어진 문장의 문법적 구조를 분석하는 것. 
LR은 입력 스트링을 좌에서 우로 읽어가며 출력으로 우 파스(right parse)를 생성하기 때문에 
이런 이름이 붙여졌다. bottom up 방식으로 구문을 분석한다. 

LR 파싱은 파싱 테이블의 구성 방법에 따라 SLR, CLR, LALR 방식으로 나눈다.
[네이버 지식백과] LR 파싱 [LR parsing] 
(컴퓨터인터넷IT용어대사전, 2011.1.20, 일진사)

 

는...무슨

저희가알고있는 Parsing 기법은

특정 문자와 특정문자 사이의 값을 잘라오는 기법을 말합니다.

자료를 원하는 형태로 가공하는 기법이라고도 설명가능하구요.

 

예를 들자면 

네이버 페이지소스중

<div class="nanum_popup_in"><div class="cnt"><span class="ques"></span><h4>나눔글꼴 설치 안내</h4>


여기서 필요한 문자가 만약 '나눔글꼴'이라는 데이터가필요합니다.

그러나 이 수백~수천줄이 되는 소스에서 문자열의 자릿수를 찾아 Copy 하기에는 방대하죠

여기서 필요한 함수는 POS 함수입니다
POS 함수는 전체데이터에서 사용자가 입력한 스트링의 자릿수를 반환해줍니다. (integer 형으로)

예를들어

var
 A : String = 'Delphi';
begin
 Showmessage(inttoStr(POS('l',A)));
end;


하시면 'Delphi'라는 데이터에서 'l' 이라는 문자의 자릿수를 리턴, 3이라는 메세지가 출력됩니다.

이처럼 POS 함수와 Copy 함수를 이용하여 우리는 파싱함수를 따로 만들어 사용할수있습니다.

SplitString, TList 의 Delimiters 속성을 이용해서 파싱도 가능한데 왜 이러한 방식을 사용하는가는

SplitString 함수의 결점과 버그, 메모리 과부하
TList 의 Delimiters 의 효율성 등을 문제로 제기할수있구요 .


Copy 시킬 데이터에서 문자열 자릿수를 POS 함수로 리턴해주어 입력받으시면됩니다.

간단히 만들어보자면

Function Parsing(Const MainString,First,Second : String):String;
var
 stmp: String;
begin
  stmp := MainString;
  stmp := Copy(stmp,POS(First,stmp) + length(First),length(stmp));
  result := Copy(stemp,1,POS(Second,sTmp)-1);
 end;


사용 방법은 직접 해보시면 알게되실겁니다 .

간단한 예로는
Parsing('Delphi','D','i');
= 'elph'
라는 정도


함수에 대한 질문이 나올걸 예상해보자면
1. 왜 stmp 라는 string 변수를 하나 더 선언하여 입력받은 데이터를 한번더 저장해주고 자르는가?
바로 Mainstring 을 Copy 시키면안되는가?

-> 처음 사용했을땐 그렇게 사용해왔으나 여러번 사용해보니 데이터의 손상, 버그 등이

발생해서 함수에서 입력받았을때 한번더 그데이터를 저장시켜주고 하는게 손상,버그등이 발견되지않았습니다.

사용하시는분들이 편한대로 사용하는게 맞죠

2. POS(First,stmp) 로 위치를 받았는데 왜 그 위치에 + length(First) ,First 라는 문자의 길이를 + 하는가?

-> 이 함수는 파싱함수입니다.
<h4>나눔글꼴</h4> 에서 저흰 나눔글꼴 이라는문자가필요하지요
이 함수를 이용해 파싱해보면 Parsing('
<h4>나눔글꼴</h4>','<h4>','</h4>');
인데 만약 length(First) 값을 + 해주지 않았다면 copy 함수의 특성상 해당 문자열까지
'h>나눔글꼴' 이라는 데이터가 리턴되게됩니다.
즉 POS 는 해당문자를 찾아도 그 문자의 시작 자릿수 를 리턴해주게됩니다.
12344566 에서44 라는 문자를 찾았을때 44의 첫번째 자릿수인 '4'를 리턴해주고되죠
그럼 뒤에 쓸모없는 데이터들이 긁혀오면 안되기때문에 length(First) 를 더해주어 이문제점을 해결할수있구요.

3. Pos(Second,stmp)-1

-> 이문제 역시 똑같습니다. 시작점을 알려주기때문에
'나눔글꼴<'을 리턴하기때문에 자릿수에서 -1 을 해준겁니다.

 

예전에 써뒀던 글을 가져왔습니다 .

 

추후 보충 설명 또는 개선 작업을 해야합니다. ^_^

댓글