2011-02-09 2 views
4

패턴 서브 루틴 이름을 사용하여/'서브 루틴'정규식 PHP의 PCRE 기능과 누군가가 다음과 같은 이상한 출력 설명 할 수 있겠죠 :PCRE 정규 표현식 내가 명명 된 서브 패턴을 실험하고

$re = "/ 
(?(DEFINE) 
    (?<a> a) 
) 

^(?&a)$ 

/x"; 

var_dump(preg_match($re, 'a', $match)); // (int) 1 as expected 
var_dump($match); // Array([0] => 'a') <-- Why? 

은 그럴 수 없어 명명 된 그룹 "a"가 결과에없는 이유 (내용 "a"포함)를 이해합니다. preg_match에서 preg_match_all으로 변경하면 "a"와 "1"이 일치 데이터에 포함되지만 둘 다 빈 문자열 만 포함됩니다. 서브 패턴이 일치하는 데이터에 사용할 수없는 그러나 경우

정말 당신이 그 (것)들을 아주 유지 보수 (이것의 좋은 예를 들어 this answer 참조) 유지하는 동안 그들을 믿을 수 없을만큼 강력 할 수 있습니다,이 방법은 정규 표현식을 작성하는 생각처럼, 그럼별로 쓸모가 없습니다.

여기에 뭔가가 누락되었거나 내가 할 수있는 일을 슬퍼해야합니까?

답변

5

이 하위 패턴이 그룹을 포착하지 않을 것이라는 점은 완벽합니다. 두 번 이상 사용하는 것이 주된 목적이므로 완전히 포착 할 수는 없습니다. 또한 기본 설정이 모든 하위 패턴을 캡처하는 것이면 이 아니라이 아닌 그룹을 캡처하여 원하지 않는 그룹을 캡처하는 것이 아니라 기본 동작이 가장 좋습니다. 그 반대는 자명합니다. (?&a) 문장 주위에 다른 그룹을 추가하여 캡처 할 수 있습니다.
PCRE.org에 대한 참조를 찾을 수 없습니다.

모든 촬영이 나중에 이전 값 을로 복귀 서브 루틴 호출시에 설정되어 있는지 괄호 : (당신이 비어있는 그룹을 기대할 수 있지만) 직접 (?<a>...) 일치하지 않기 때문에 가장 가까운 관련 인이있다 .

그것은 Perl manual에 명확 (관련 부분이 강조) :

사용될 수있는이 같은 방법의 예는 다음과 같습니다 캡처 버퍼가 내부 일치

/(?<NAME>(?&NAME_PAT))(?<ADDR>(?&ADDRESS_PAT)) 
(?(DEFINE) 
(?<NAME_PAT>....) 
(?<ADRESS_PAT>....) 
)/x 

하는 것으로 재귀가을 반환 한 후에 재귀가 액세스 할 수 없으므로 캡처 버퍼의 추가 계층이 필요합니다.

+1

네, 맞습니다. 이것은'(? (DEFINE) ...)'이 작동하는 방식입니다. 서브 루틴을 선언하고 싶습니다. 나는 때로는 내 머리 속에 두 가지를 유지하기 위해, 정의 할 수없는 캡쳐 그룹과 캡쳐 할 수없는 캡쳐 링 그룹을위한 소문자로 모두 캡을 사용한다. 주어진 해결책의 더 이상을보십시오 [이 답변에서] (http://stackoverflow.com/questions/4284176/doubt-in-parsing-data-in-perl-where-amgoing-wrong/4286326# 4286326) 두 가지 방법으로 명명 된 그룹을 사용하는 방법 : 호출 및 캡처. 캡쳐 된 것들은'$ + {VALUE} '나'@ ⁠ + ⁠ {qw }'와 같은'% +'해시를 빠져 나옵니다. – tchrist

+0

이 문제를 해결해 주셔서 감사합니다. – connec