정규식 다시 질문드립니다..

정규식 다시 질문드립니다..

QA

정규식 다시 질문드립니다..

본문

정규식으로 서브도메인을 추출하기위해서 이렇게 소스가있는데


preg_match("/(([a-z0-9\-]+\.)*)([a-z0-9\-]+)\.([a-z]{3,4}|[a-z]{2,3}\.[a-z]{2})(\:[0-9]+)?$/", $test, $matches); 


$matches 배열의 [1]에 서브도메인에서 접속했다면 서브도메인명만 따로 들어갑니다.

com / co.kr / net 의 경우는 문제가 없이 정상적으로 동작합니다.


naver.com 의 경우

Array
(
    [0] => naver.com
    [1] => 
    [2] => 
    [3] => naver
    [4] => com
) 


naver.co.kr 의 경우

Array
(
    [0] => naver.co.kr
    [1] => 
    [2] => 
    [3] => naver
    [4] => co.kr
) 


위의 2개의 도메인을 테스트 해보았을때 서브도메인이 아니기 때문에 [1]배열에는 값이 없습니다.


test.naver.com 의 경우

Array
(
    [0] => test.naver.com
    [1] => test.
    [2] => test.
    [3] => naver
    [4] => com
) 


test.naver.co.kr 의 경우

Array
(
    [0] => test.naver.co.kr
    [1] => test.
    [2] => test.
    [3] => naver
    [4] => co.kr
) 


$matches[1] 배열에 정상적으로 서브도메인이 추출되었습니다.


아래의 질문으로 kr의 정규식도 가져오기위해 아래의 질문의 답변으로 돌린결과


preg_match("/(([a-z0-9\-]+\.)*)([a-z0-9\-]+)\.([a-z]{2}|[a-z]{3,4}|[a-z]{2,3}\.[a-z]{2})(\:[0-9]+)?$/", $test, $matches); 


.com은 문제가없지만 co.kr에서 문제가 발생했습니다..

위의 정규식으로 naver.co.kr로 추출결과

Array
(
    [0] => naver.co.kr
    [1] => naver.
    [2] => naver.
    [3] => co
    [4] => kr
) 

서브도메인이 아니기 때문에 [1], [2] 이 비어야 하는데 naver라는 단어가 들어갔습니다.


그렇다면 서브도메인인 kr 도메인으로 추출을해겠습니다.

test.naver.co.kr 로 추출결과

Array
(
    [0] => test.naver.co.kr
    [1] => test.naver.
    [2] => naver.
    [3] => co
    [4] => kr
) 

제가 원하는 서브도메인 test는 배열에 들어가지 않았습니다..


정규식을 어떻게 수정을해야

서브도메인만 배열에 잘 받을수 있을까요..

이 질문에 댓글 쓰기 :

답변 3

도메인 규칙을 보면 가장 우측에 있는 부분부터

top-level, second-level, lower level, ... 입니다.


예를 들어 example.com 은 com 도메인의 서브(2차)도메인인 것이죠

자세한 사항은 하기 링크에 정의되어 있습니다.

https://en.wikipedia.org/wiki/Domain_name#Domain_name_space


그렇기 때문에 co.kr 이라는 도메인도 co 부터는 서브 도메인인 것인데

대한민국 기준으로 co.kr 이 최상위 도메인이라고 생각하게 되는것 같습니다.


예를 들어 a.naver.co.kr 의 경우

1차 도메인은 kr 인데

대한민국 사람들은 보통 co.kr 을 최상위 도메인 호스트,

도메인 이름을 naver 라고 인식하고 있는 형태입니다.

그리고 2차 도메인을 a. 부터 라고 인식하고 있죠


애초에 대한민국 기준으로 판단하려다 보니

여기서부터 기준이 꼬여서 생기는 문제 같습니다.


도메인을 관리하는 루트기관 관점에서 바라볼때

a: 4차, naver: 3차, co: 2차 대한민국 관리 산하 도메인, kr: 1차 최상위 도메인

가 될 것이고

서브도메인 a.naver.com 의 메인도메인은 naver.com (com 도메인)

서브도메인 a.naver.incheon.kr 의 메인도메인은 incheon.kr (kr 도메인)

이 될 것입니다.


co.kr 은 대한민국이라는 국가가 최상위 루트기관 으로부터

2차도메인 co 를 호스팅 받는 형태라고 생각하면 될것 같습니다.


그러면 도메인의 차수를 나누는 방법 또한 간단해 지기 때문에

굳이 정규식으로 복잡하게 표현할 필요가 없어집니다.


<?php
function domain_info($domain) {
    $rtn = explode('.', $domain);

    // how-to 1
    $rtn = array_reverse($rtn);

    // how-to 2
    //krsort($rtn);
    //$rtn = array_values($rtn);

    return $rtn;
}

$i = domain_info('a.b.c.naver.co.kr');
print('<pre>');
print_r($i);
print('</pre>');
?>


문제는 2차를 1차 처럼 판단하고자 하는 기준을 어떻게 세우느냐 일것 같고

어느정도 자동화가 될 수는 있겠으나,

결론적으로는 수동적인 예외처리가 필요한 부분이 될것 같습니다.


참고로 top-level 도메인 목록은 다음 페이지에 정리되어 있습니다.

https://www.iana.org/domains/root/db


추가적으로 dig tool ( https://ko.wikipedia.org/wiki/Dig ) 질의도 고려해 보았으나,

시스템에 dig 라는 툴이 설치 되었을 경우를 가정하더라도

대한민국 국가내에서 질의를 할때와

타국가, 타 네임서버 기준으로 질의를 하게 될경우

각각 다른 응답이 떨어지므로 무용지물인것 같네요.

전 질문에 너무 성의없이 답글을 달아 미안하기도 하고 해서

좀 살펴 봤습니다.

문제는 예제의 naver도 숫자가 포함되지 않은 영문자기도 한다는걸로 보입니다.

완전하지는 않지만 아래 처럼 하시면 서브도메인 끄집어 내는대는 문제 없을걸로 보입니다.

뒷 부분 조금 손을 봤고 Ungreedy modifier를 사용했습니다. 대문자 U

test.naver.co.kr 과 naver.co.kr 에서 뒷부분이 완전하지 않게 나오지만

잘 다듬어 사용하세요 ㅎㅎ


preg_match("/(([a-z0-9\-]+\.)*)([a-z0-9\-]+)\.([a-z]{2,4})(\.[a-z]{2})?$/U", $test, $matches);

preg_match("/(([a-z0-9\-]+\.)*)([a-z0-9\-]+)\.(([a-z]{2,4})(\.[a-z]{2})?)$/U", $test, $matches);
뒷부분을 하위패턴으로 한번도 묶어 버리닌까 잘되기는 합니다.

답변을 작성하시기 전에 로그인 해주세요.
전체 123,162 | RSS
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT