2010-06-23 7 views
0

PHP에서 생성 된 데이터를 HTML 페이지로 대체하기 위해 PHP에서 '엔진'이라는 간단한 템플릿을 만들었습니다. 작동 방식은 다음과 같습니다 내 주요 템플릿 파일에서PHP - Regex에 대한 도움이 필요합니다.

, 정말 같은 변수를 가지고 :

<title><!-- %{title}% --></title> 

그때 메인 페이지로드를 위해 해당 변수에 데이터를 할당 그때가

$assign = array (
    'title' => 'my website - ' 
); 

콘텐츠 페이지 용으로로드되는 별도의 템플릿 블록 위의 코드는 실제로 머리글과 바닥 글을 처리합니다. 이러한 '내용 템플릿 파일'중 하나, 난과 같이 변수를 가지고 :

<!-- %{title=content page}% --> 

을이 실행됩니다되면, 메인 템플릿 데이터가 결과적으로 콘텐츠 페이지 변수를 포함하도록 편집 :

<title>my website - content page</title> 

다음 코드로이 작업을 수행합니다.

if (preg_match('/<!-- %{title=\s*(.*?)}% -->/s', $string, $matches)) { 
    // Find variable names in the form of %{varName=new data to append}% 
    // If found, append that new data to the exisiting data 
    $string  = preg_replace('/<!-- %{title=\s*(.*?)}% -->/s', null, $string); 
    $varData[$i] .= $matches[1]; 
} 

기본적으로 템플릿 변수를 제거한 다음 변수 데이터를 기존 변수에 할당합니다. 자,이 모든 것이 잘 작동합니다. 내가 겪고있는 문제는 템플릿 변수를 중첩하는 것입니다. 내가 다음과 같이하면 :

<!-- %{title=content page (author: <!-- %{name}% -->) --> 

패턴은 때때로 각 변수의 시작 및 종료 태그를 엉망으로 만듭니다.

정규식을 수정하면 어떻게 되나요?

감사합니다.

답변

4

대답은 당신이 정규식으로 이것을하지 않는다는 것입니다. 정규 표현식은 정규 언어입니다. 중첩 작업을 시작하면 더 이상 일반 언어가 아닙니다. 최소한 문맥 자유 언어 ("CFL")입니다. CFL은 스택으로 만 처리 할 수 ​​있습니다 (모호하지 않다고 가정).

특히 정규 언어는 유한 상태 기계 ("FSM")로 나타낼 수 있습니다. CFL은 푸시 다운 오토 마톤 ("PDA")을 필요로합니다.

차이의 예

는 HTML에서 태그를 중첩 :

<div> 
    <div>inner</div> 
</div> 

내 조언은 자신의 템플릿 언어를 쓰지 않는다이다. 그게 끝났어. 여러 번. Zend, Kohana 등에서 Smarty 또는 무언가를 사용하십시오. 자신 만의 글을 쓰면 제대로하십시오. 그것을 분석하십시오.

+0

저는 정규 표현식에별로 좋지 않습니다. 대안을 추천 할 수 있다면, 나는 그것을위한 전부입니다. 내가하는 일을 어떻게 또 성취 할 수 있니? – dave

0

내가 묻고있는 내용을 묻는다면, 그것은 사실상 불가능합니다. 귀하의 질문을 올바르게 읽으면 임의로 중첩 된 <!-- ... --> 시퀀스를 내부의 특정 항목과 일치 시키려고합니다. 불행히도 정규 표현식은 특정 클래스의 클래스에만 일치 할 수 있습니다. 모든 정규 표현식은 regular language과 일치 할 수 있습니다. 하나의 잘 알려진 언어 인 이 아닌은 정확히 일치하려는 단어 인 language of balanced parentheses (also known as the the Dyck language)입니다. 임의로 중첩 된 주석 문자열을 일치 시키려면보다 강력한 도구가 필요합니다. 이미 존재하는 PHP 템플릿 엔진이 있다고 확신합니다. 당신은 그 중 하나를 들여다 볼 수 있습니다.

+0

한 문장으로이 작업을 수행하는 것은 불가능할 수도 있지만 (100 % 확신 할 수는 있지만) 반복적으로 또는 반복적으로 수행 할 수 있습니다. PHP (또는 그 언어를 지원하는 언어)가 사용될 때 정규 표현식이 격리 된 것보다 훨씬 강력 해집니다. – Andrew

0

당신이

  • preg_match_all()으로 preg_match()를 교체해야 문제를 해결하려면,
  • 패턴을 찾아 마지막 패턴에서 첫 패턴으로 바꿉니다.
  • '/<!-- %{title=\s*([^}]*?)}% -->/s'과 같이 더 제한적인 패턴을 사용합니다.
0

나는 과거에 비슷한 일을 해왔고, 당신이 한 동일한 중첩 문제가 발생했습니다. 귀하의 경우, 내가 무엇을 할 것인지 반복적으로 텍스트를 검색하여 매치 (매치를 반복하면서 한 번 검색하는 것보다)를 검색하고 닫는 문자열을 포함하지 않는 것을 검색하여 원하는 문자열을 추출합니다. 귀하의 경우에는

, 아마도 다음과 같을 것이다 :이 같은

/(<!--([^(-->)]*?)-->)/ 

정규 표현식에 설명하는 악몽이지만, 기본적으로 ([^(-->)]*)이 닫는 태그를 포함하지 않는 문자열을 찾을 수 있습니다 (하자 전화 그 AAA). 일치하는 그룹 내부에 템플릿 태그 인 (<!--AAA-->)이 있습니다.

나는 이런 종류의 템플리트 작성 방법이 일을하는 잘못된 방법이라고 확신하지만 나는 그것을 더 잘 수행 할만큼 충분히 알지 못했습니다. ASP와 ColdFusion에서 HTML 안에 스크립트 태그를 중첩시켜야한다는 것을 항상 귀찮게하고 있습니다.

대부분의 Regexes는 JavaScript로 작성되어 있으므로 PHP가 Perl을 통해 제공하는 멋진 뉘앙스가 누락 될 수 있습니다. 누군가가 이것을 더 깔끔하게 쓸 수 있다면 행복 할 것입니다.

1

왜 자신 만의 템플릿 엔진을 사용하고 있습니까? 이런 종류의 복잡성을 원한다면 이미 솔루션을 제안한 많은 곳이 있습니다. Smarty 또는 그와 비슷한 것을 연결해야합니다.

0

정규식을 사용하지는 않았지만 과거에도이 문제가 발생했습니다.

당신이 strrpos (PHP5 +)를 사용하여 시작 태그, 당신의 구문 <!-- %{ 위해 오른쪽에서 왼쪽으로 검색 대신하는 경우, 그 다음 닫는 태그의 첫 번째 항목에 대해 앞으로 검색 한 다음 먼저 덩어리를 교체, 당신은 것입니다 가장 안쪽으로 중첩 된 변수를 먼저 바꿉니다. 이렇게하면 문제가 해결됩니다.

다른 방법으로 닫는 태그를 찾은 다음 뒤로 태그를 사용하여 해당 시작 태그를 찾을 수도 있습니다.

관련 문제