2015-01-29 1 views
1

내 이전에 대해서는 post 정규 표현식과 일치 시키려고하는데 모두 클래스 파일의 명령문을 사용합니다.같은 이름의 다중 서브 패턴 얻기

<?php 
use Vendor\ProjectArticle\Model\Peer, 
    Vendor\Library\Template; 
use Vendor\Blablabla; 

$file = file_get_contents($class_path); 
$a = preg_match_all('#use (?:(?<ns>[^,;]+),?)+;#mi', $file, $use); 
var_dump(array('$a' => $a, '$use' => $use)); 

불행히도 하나의 사용 선언문에 여러 개의 클래스 이름이있을 경우 사용되는 모든 네임 스페이스에 대해 축복을받지 못했습니다. 마지막으로 일치하는 항목 만 저장됩니다.

Array 
(
    [$a] => 2 
    [$use] => Array 
     (
      [0] => Array 
       (
        [0] => use Vendor\ProjectArticle\Model\Peer, 
    Vendor\Library\Template; 
        [1] => use Vendor\Blablabla; 
       ) 

      [ns] => Array 
       (
        [0] => 
    Vendor\Library\Template 
        [1] => Vendor\Blablabla 
       ) 

      [1] => Array 
       (
        [0] => 
    Vendor\Library\Template 
        [1] => Vendor\Blablabla 
       ) 
     ) 
) 

일부 패턴 수정 자 등으로이 작업을 수행 할 수 있습니까?

~ 감사합니다

답변

1

이의 \G 앵커를 사용할 수 있어야합니다.

# '~(?:(?!\A)\G|^Use\s+),?\s*(?<ns>[^,;]+)(?=(?:,|[^,;]*)*;)~mi' 

(?xmi-)      # Inline modifier = expanded, multiline, case insensitive 
(?: 
     (?! \A)      # Not beginning of string 
     \G       # If matched before, start at end of last match 
    |        # or, 
    ^Use \s+      # Beginning of line then 'Use' + whitespace 
) 

,? \s*      # Whitespace trim 
(?<ns> [^,;]+)    # (1), A namespace value 

(?=       # Lookahead, each match validates a final ';' 
     (?: , | [^,;]*)* 
     ; 
) 

출력 : 당신은 그냥이 답변 나를 멀리 날려

** Grp 0 - (pos 0 , len 36) 
use Vendor\ProjectArticle\Model\Peer 
** Grp 1 - (pos 4 , len 32) 
Vendor\ProjectArticle\Model\Peer 

--------------------- 

** Grp 0 - (pos 36 , len 30) 
, 
    Vendor\Library\Template 
** Grp 1 - (pos 43 , len 23) 
Vendor\Library\Template 

--------------------- 

** Grp 0 - (pos 69 , len 20) 
use Vendor\Blablabla 
** Grp 1 - (pos 73 , len 16) 
Vendor\Blablabla 
+0

. 와우 정말 ... (?! \ A)는 한 줄의 범위 내에있는 문자열의 시작이 아니라는 뜻인가요? – starach

+1

@starach - 예,'\ G'는 이전의 매치 생성 후 매치를 시도합니다. 새로운 문자열에 적용되면,'\ G'는 기본적으로 _TRUE_ 상태입니다. 처음으로 일치하려고 할 때. 이 위치는'\ A'가있는 곳입니다. 이 시점과 위치에서'\ G'를 _FALSE_로 바꾸려면'(?! \ A)'가 필요합니다. 그런 다음'(?! \ A)'어설 션은 결코 거짓이 아니므로 '\ G'의 진실. '\ G'는 true/false 내부 플래그를 유지한다는 것을 기억하십시오. – sln

+0

불편을 끼쳐 드려 죄송합니다. 제 [두 번째 문제 링크] (http://stackoverflow.com/questions/28270832/capturing-all-method-arguments-default-values)에서 저를 보내거나 답변을 다시 게시 할 수 있습니까? 나는 그것이 내 문제를 거의 해결했다고 생각하지만 afk로 가야만했다. 그리고 내가 돌아 왔을 때 그들은 나의 주제를 막았고, 이제는 당신의 답장이 빠져있다. – starach