테스트 사이트 - 개발 중인 베타 버전입니다

정규표현식 관련 내장함수 preg_match_all

· 12년 전 · 9359 · 21

대단할것은 없는 강좌이지만,
제 강좌를 출처를 밝히고 외부로 퍼가는 것은 허용하지만,
다른 강좌의 자료나 책의 자료로 사용되거나 부분적인 인용은 허용하지 않습니다.

강좌는 php 5. 대를 기준으로 하며, PCRE (펄과 호환 되는 정규표현식)을 다룹니다.
PCRE 는 preg_ 로 시작되는 내장함수와 함께 사용되어지는 정규표현식을 말합니다.

PCRE > 정규표현식 관련 내장함수 preg_match_all

이전 내용에서는 내장함수 preg_grep 과 preg_match 에 대하여 알아보았습니다.
이번 내용에서는 내장함수 preg_match_all 에 대해서 알아보겠습니다 .

int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )

설명 : 입력받은 문자열이 주어진 패턴과 일치하는 검사, 단, preg_match 와는 다르게 한번만 찾고 마는 것이 아니라 모두 찾습니다.

인자 :
    -> string $pattern : 문자열로 된 정규 표현식 패턴
    -> string $subject : 검사하고자 하는 문자열
    -> array &$matches : 생략 가능하며, 사용시 패턴에 매치되는 내용을 $matches 배열에 담아줌
    -> int $flags : 생략가능하며, PREG_PATTERN_ORDER (1) , PREG_SET_ORDER (2) , PREG_OFFSET_CAPTURE (256) 상수와 같이 사용할수 있으며 생략시 PREG_PATTERN_ORDER 가 기본값
    -> int $offset : 생략가능하며, 검사 시작 지점을 지정할수 있음

결과값 :
    패턴과 매치되는 문자열을 찾았을 때는 전체 매치된 횟수를 반환, 못 찾았을 때는 false 를 반환.
용도 :
    특정 패턴의 문자열이 몇개 존재하는지 여부를 확인 할때나,
    특정 패턴의 문자열을 모두 찾아서 그 문자열을 모두 알고 싶을때 사용합니다
예제25> test25.php

<?

$subject = '
<ul>

<li><a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크</a></li>
<li><a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실<span>13</span></a></li>
<li><a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌</a></li>
<li><a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰<span>9</span></a></li>
<li><a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인</a></li>            </ul>
';

$pattern = '`<a href="([^>]+)">([^<]+)`'; // 링크와 링크 제목을 뽑음

preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER);

echo "PREG_PATTERN_ORDER 을 사용한 결과 \$matches : " . PHP_EOL ;
print_r($matches);
echo PHP_EOL . PHP_EOL ;

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);

echo "PREG_SET_ORDER 을 사용한 결과 \$matches : " . PHP_EOL ;
print_r($matches);
echo PHP_EOL . PHP_EOL ;

preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);

echo "PREG_OFFSET_CAPTURE 을 사용한 결과 \$matches : " . PHP_EOL ;
print_r($matches);
echo PHP_EOL . PHP_EOL ;

?>


결과 :

PREG_PATTERN_ORDER 을 사용한 결과 $matches : 
Array
(
    [0] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크
            [1] => <a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실
            [2] => <a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌
            [3] => <a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰
            [4] => <a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인
        )

    [1] => Array
        (
            [0] => ../../bbs/board.php?bo_table=pg_talk
            [1] => ../../bbs/board.php?bo_table=pg_tip
            [2] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
            [3] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
            [4] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
        )

    [2] => Array
        (
            [0] => 개발자 토크
            [1] => 개발자 팁자료실
            [2] => 프로그램 강좌
            [3] => 프로그램 의뢰
            [4] => 개발자 구인
        )

)


PREG_SET_ORDER 을 사용한 결과 $matches : 
Array
(
    [0] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크
            [1] => ../../bbs/board.php?bo_table=pg_talk
            [2] => 개발자 토크
        )

    [1] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실
            [1] => ../../bbs/board.php?bo_table=pg_tip
            [2] => 개발자 팁자료실
        )

    [2] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌
            [1] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
            [2] => 프로그램 강좌
        )

    [3] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰
            [1] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
            [2] => 프로그램 의뢰
        )

    [4] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인
            [1] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
            [2] => 개발자 구인
        )

)


PREG_OFFSET_CAPTURE 을 사용한 결과 $matches : 
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크
                    [1] => 14
                )

            [1] => Array
                (
                    [0] => <a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실
                    [1] => 92
                )

            [2] => Array
                (
                    [0] => <a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌
                    [1] => 190
                )

            [3] => Array
                (
                    [0] => <a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰
                    [1] => 290
                )

            [4] => Array
                (
                    [0] => <a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인
                    [1] => 430
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [0] => ../../bbs/board.php?bo_table=pg_talk
                    [1] => 23
                )

            [1] => Array
                (
                    [0] => ../../bbs/board.php?bo_table=pg_tip
                    [1] => 101
                )

            [2] => Array
                (
                    [0] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
                    [1] => 199
                )

            [3] => Array
                (
                    [0] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
                    [1] => 299
                )

            [4] => Array
                (
                    [0] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
                    [1] => 439
                )

        )

    [2] => Array
        (
            [0] => Array
                (
                    [0] => 개발자 토크
                    [1] => 61
                )

            [1] => Array
                (
                    [0] => 개발자 팁자료실
                    [1] => 138
                )

            [2] => Array
                (
                    [0] => 프로그램 강좌
                    [1] => 256
                )

            [3] => Array
                (
                    [0] => 프로그램 의뢰
                    [1] => 382
                )

            [4] => Array
                (
                    [0] => 개발자 구인
                    [1] => 510
                )

        )

)

※ 위 테스트 결과에서 알수 있듯이
PREG_PATTERN_ORDER 를 사용하면 () 를 친 순서대로 배열이 담긴다는 것을 알수 있습니다.
[0] 에는 패턴과 일치 하는 전체 문자열,
[1] 에는 첫번째 () 와 일치하는 문자열,
[2] 에는 두번째 () 와 일치하는 문자열이 각각 매치되는 순서대로 저장되는 것을 알수 있습니다.

PREG_SET_ORDER 를 사용하면 괄호 순서대로 배열에 저장하는 것이 아니라,
전체 문자열, 첫번째 문자열, 두번째 문자열을 한 세트로 하여 배열이 저장되는 것을 알수 있습니다.

PREG_OFFSET_CAPTURE 를 사용하면 기본 저장 방식은 PREG_PATTERN_ORDER 와 같되 preg_match 에서와 마찬가지로 해당 매치되는 문자열이 전체 문자열에서 어디서 시작되는지 시작 지점을 같이 배열로 저장되는 것을 알수 있습니다.

네번째인자를 생략 할 경우 PREG_PATTERN_ORDER 와 같습니다. 즉, PREG_PATTERN_ORDER 이 기본값입니다.

※ 유용한 표현 두가지

1. 배열키명 지정 서브패턴
(?P<받을키명>패턴) 와 같은 형태로 쓰이며,
해당 () 안의 정규표현식에 매치되는 문자열은 세번째인자의 배열에 지정된 키명으로 저장하겠다는 뜻입니다.
이렇게 하면 숫자배열키를 기본적으로 사용할때 혼돈될수 있는 부분을 해결할수 있습니다.

2. 특정문자 최대매치 메타문자
문자*?패턴 나 문자+?패턴 와 같이 수량을 나타내는 메타문자 * 나 + 과 ? 의 결합 형태로 쓰이며,
다음 패턴을 최초로 만나기 전까지 바로 앞의 문자가 최대로 매치하도록 지정합니다.
기존 문자* 와 문자+ 와 다른것은 다음패턴을 포함하지 않습니다.


예제26> test26.php

<?

$subject = '
<ul>

<li><a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크</a></li>
<li><a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실<span>13</span></a></li>
<li><a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌</a></li>
<li><a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰<span>9</span></a></li>
<li><a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인</a></li>            </ul>
';

$pattern = '`<a href="(?<link>[^>]+)">(?<title>[^<]+)`'; // 링크와 링크 제목을 뽑음

preg_match($pattern, $subject, $matches);

echo "preg_match를 사용한 \$matches : " . PHP_EOL ;
print_r($matches);
echo PHP_EOL . PHP_EOL ;

preg_match_all($pattern, $subject, $matches);

echo "preg_match_all를 사용한 \$matches : " . PHP_EOL ;
print_r($matches);
echo PHP_EOL . PHP_EOL ;

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);

echo "preg_match_all 과 PREG_SET_ORDER 를 사용한 \$matches : " . PHP_EOL ;
print_r($matches);

?>


결과 :

preg_match를 사용한 $matches : 
Array
(
    [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크
    [link] => ../../bbs/board.php?bo_table=pg_talk
    [1] => ../../bbs/board.php?bo_table=pg_talk
    [title] => 개발자 토크
    [2] => 개발자 토크
)


preg_match_all를 사용한 $matches : 
Array
(
    [0] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크
            [1] => <a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실
            [2] => <a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌
            [3] => <a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰
            [4] => <a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인
        )

    [link] => Array
        (
            [0] => ../../bbs/board.php?bo_table=pg_talk
            [1] => ../../bbs/board.php?bo_table=pg_tip
            [2] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
            [3] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
            [4] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
        )

    [1] => Array
        (
            [0] => ../../bbs/board.php?bo_table=pg_talk
            [1] => ../../bbs/board.php?bo_table=pg_tip
            [2] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
            [3] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
            [4] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
        )

    [title] => Array
        (
            [0] => 개발자 토크
            [1] => 개발자 팁자료실
            [2] => 프로그램 강좌
            [3] => 프로그램 의뢰
            [4] => 개발자 구인
        )

    [2] => Array
        (
            [0] => 개발자 토크
            [1] => 개발자 팁자료실
            [2] => 프로그램 강좌
            [3] => 프로그램 의뢰
            [4] => 개발자 구인
        )

)


preg_match_all 과 PREG_SET_ORDER 를 사용한 $matches : 
Array
(
    [0] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크
            [link] => ../../bbs/board.php?bo_table=pg_talk
            [1] => ../../bbs/board.php?bo_table=pg_talk
            [title] => 개발자 토크
            [2] => 개발자 토크
        )

    [1] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실
            [link] => ../../bbs/board.php?bo_table=pg_tip
            [1] => ../../bbs/board.php?bo_table=pg_tip
            [title] => 개발자 팁자료실
            [2] => 개발자 팁자료실
        )

    [2] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌
            [link] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
            [1] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
            [title] => 프로그램 강좌
            [2] => 프로그램 강좌
        )

    [3] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰
            [link] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
            [1] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
            [title] => 프로그램 의뢰
            [2] => 프로그램 의뢰
        )

    [4] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인
            [link] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
            [1] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
            [title] => 개발자 구인
            [2] => 개발자 구인
        )

)


예제27> test27.php

<?

//뽑아내고자 하는 내용이 여러개가 붙어있다.
$subject = '<ul><li><a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크</a></li><li><a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실<span>13</span></a></li><li><a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌</a></li><li><a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰<span>9</span></a></li><li><a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인</a></li>            </ul>';

$pattern = '`<a href="(.+)">(.+)</a>`'; // 링크와 링크 제목을 뽑음, .+ 안에 </a> 도 포함됨

preg_match_all($pattern, $subject, $matches);

echo htmlspecialchars($pattern) . " 을 사용한 \$matches : " . PHP_EOL ;
print_r($matches);
echo PHP_EOL . PHP_EOL ;

$pattern = '`<a href="(.+?)">(.+?)</a>`'; // 링크와 링크 제목을 뽑음, .+ 안에 </a> 가 포함 안됨

preg_match_all($pattern, $subject, $matches);

echo htmlspecialchars($pattern) . " 을 사용한 \$matches : " . PHP_EOL ;
print_r($matches);

?>


결과 :

`<a href="(.+)">(.+)</a>` 을 사용한 $matches : 
Array
(
    [0] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크</a></li><li><a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실<span>13</span></a></li><li><a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌</a></li><li><a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰<span>9</span></a></li><li><a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인</a>
        )

    [1] => Array
        (
            [0] => ../../bbs/board.php?bo_table=pg_talk">개발자 토크</a></li><li><a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실<span>13</span></a></li><li><a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌</a></li><li><a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰<span>9</span></a></li><li><a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
        )

    [2] => Array
        (
            [0] => 개발자 구인
        )

)


`<a href="(.+?)">(.+?)</a>` 을 사용한 $matches : 
Array
(
    [0] => Array
        (
            [0] => <a href="../../bbs/board.php?bo_table=pg_talk">개발자 토크</a>
            [1] => <a href="../../bbs/board.php?bo_table=pg_tip">개발자 팁자료실<span>13</span></a>
            [2] => <a href="../../bbs/board.php?bo_table=pg_lecture" class="lnb_div">프로그램 강좌</a>
            [3] => <a href="../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">프로그램 의뢰<span>9</span></a>
            [4] => <a href="../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90">개발자 구인</a>
        )

    [1] => Array
        (
            [0] => ../../bbs/board.php?bo_table=pg_talk
            [1] => ../../bbs/board.php?bo_table=pg_tip
            [2] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
            [3] => ../../bbs/board.php?bo_table=request&sca=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8
            [4] => ../../bbs/board.php?bo_table=guin&sca=%EA%B0%9C%EB%B0%9C%EC%9E%90
        )

    [2] => Array
        (
            [0] => 개발자 토크
            [1] => 개발자 팁자료실<span>13</span>
            [2] => 프로그램 강좌
            [3] => 프로그램 의뢰<span>9</span>
            [4] => 개발자 구인
        )

)

문제) 위 예제에서 공통적으로 [2] => ../../bbs/board.php?bo_table=pg_lecture" class="lnb_div
와 같이 class 까지 매치되는 부분이 있습니다.
원래 원하는 결과는 순수한 링크 부분 이므로, 위 예제들의 정규표현식을 수정하여
완전한 결과가 되도록 만들어 보십시오.

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 21개

멋지십니다! 감사합니다.
감사합니다.
감사합니다. 잘만 사용하면 좋은플그램이 나오겠네요 ㅎㅎ
네.. 고맙습니다.
12년 전
좋은 강좌네요
감사합니다.^^
네 감사합니다.
예제와 결과가 잘못 붙어서 다시 수정하였습니다.
좋은자료 항상 감사드립니다....^^
빨리 하던일 마무리하고 정독하고 복습도 해야 할텐데......
오늘도 슬쩍 수박 겉할기식으로 보고 갑니다....ㅠㅠ
항상 저도 감사합니다.
12년 전
항상 감사합니다.

게시글 목록

번호 제목
18790
JavaScript 공백제거
18788
18786
18783
18780
18769
5549
27272
27267
30785
30782
27264
18767
18765
18764
18763
5546
18760
18758
18755
18752
27256
27247
5539
18750
27244
27243
18749
18747
18745
18741
18740
18738
18731
18730
27240
5535
18728
18726
18724
5532
26500
27237
5529
30776
18721
20725
27232
18719
JavaScript 퀵메뉴 1
18717
18714
18712
18709
27213
27200
18706
18704
18702
18701
18700
18698
18697
18696
18694
5525
27199
18691
5515
5510
5501
18690
18687
5496
18686
18676
26496
18675
30773
18671
30767
18667
18658
18650
18648
5494
5490
20705
5485
18645
27194
20684
18642
5482
27185
5478
5473
5467
18636
5462
5443