2012-02-04 5 views
2

어떤 패턴을 여러 번 캡처해야하며 이전, 이후 및 사이를 기억하고 있어야합니다. 예를 들어 일부 텍스트가 좀 더 텍스트 "를 캡처 할 수있는"여러 정규식 캡쳐

좀 더 텍스트를 텍스트를 구분하는 토큰을 캡처 할 수 있습니다 예측할 수

유일한 것 "을 캡처 할" . 캡쳐 된 텍스트 자체는 매번 다릅니다. 결국 나는

그것은 하나의 캡처 라인 작동
if (preg_match("/(.*?)(\".*?\")(.*)/", $line, $m) 
    $res .= $m[1] . '<span class="a">' . $m[2] . '</span>' . $m[3]; 

을 시도 그래서

some text <span class="a">"to be captured"</span> some more text <span 
class="a">"to be captured"</span> some more text 

처럼, 그 촬영 된 부분 주위에 CSS를 스팬을 배치해야합니다. preg_match_all을 사용하여이 문제를 해결할 수는 없지만 정규식 자체를 변경해야 할 수도 있습니다. 그러나 어떻게해야할지 모르겠습니다.

답변

3

preg_replace를 사용해 보셨습니까?

$line = preg_replace("/(\".*?\")/", 
        '<span class="a">$1</span>', 
        $line 
); 

ps : 아직 OP없이 어떤 문제인지 모르겠다.

$matchs_and_in_between = preg_split('/"(.*?)"/', $src, 
          PREG_SPLIT_DELIM_CAPTURE); 

: 당신은 구분 기호의 집합이있는 경우 기본적으로 모든 것을 캡처하지만 특정 부분을 분리해야 할 때 다음 정규 표현식은 다음 preg_split을 사용할 수 있습니다,

$str = 'some text "to be captured" some more text #to be *captured# 
      some more text* but I would capture that*'; 
echo preg_replace('/(("|#|\*).*?\\2)/s', 
        '<span class="a">$1</span>', 
        $str); 
+0

이것은 의도하지 않은 텍스트 ""와 일치합니다. – Grilse

+0

@Grilse 질문에서 따지지 않습니다. '예측할 수있는 유일한 것들은 캡처 할 텍스트를 정하는 토큰입니다. ' – Cheery

+0

다시 말하면 다음과 같습니다. 구분 기호가 두 개 이상인 경우 구분 기호 2와 3 사이의 모든 텍스트와 일치하며 이는 의도하지 않은 것입니다 . – Grilse

0

수 트릭이 깃발입니다. 결과 배열을 반복해야합니다. 모든 두 번째 항목은 정규식으로 지정한 항목입니다. 나머지는 중간 부분입니다.

1

내가 PHP를 모르지만, 정규식 전적으로 보는 것은 당신이 검색해야 ([^"]*)(".*?")를이 줄 것이 $1<span class="a">$2</span>

some text "to be captured" some more text "to be captured" some more text 
some text "to be captured" some more text "to be captured" 

로 교체 :

some text <span class="a">"to be captured"</span> some more text <span class="a">"to be captured"</span> some more text 
some text <span class="a">"to be captured"</span> some more text <span class="a">"to be captured"</span> 

을 :: 편집 : 이 PHP 코드가 작동하는 것 같다 :

$line = 'some text "to be captured" some more text "to be captured" some more text'; 

$line2 = preg_replace('/([^"]*)(".*?")/', htmlspecialchars('$1<span class="a">$2</span>'),$line); 

echo $line2; 
1

코드가 작동하지 않는 주된 이유는 세 번째 그룹 인 (.*)이 모든 나머지 따옴표를 포함하여 첫 번째 따옴표로 묶은 섹션 다음에 오는 모든 것을 거들게하기 때문입니다. .이 줄 바꿈 문자와 일치하면 나머지 줄뿐만 아니라 나머지 줄의 모든 따옴표도 모두 먹게됩니다.

@ Cheery의 솔루션은 제 3의 그룹을 비 욕심 많게 만들어이 문제를 해결합니다. (.*?). 그게 효과가 있지만, 세 번째 그룹은 결코 어떤 것도 포착하지 않기 때문입니다. 모든 것을 소비하는 대신, 아무것도 소비하지 않고 시작합니다. 그건 받아 들일 수 있고, 그 이후에는 더 많은 것을 소비하도록 정규 표현식에서 아무 것도 없기 때문에 거기에서 멈 춥니 다.

이 문제를 해결하는 올바른 방법은 에만 강조 표시하려는 부분을 일치시키는 것입니다.그것을 둘러싸고있는 태그에 다시 넣어 캡처 그룹을 사용, 혼자 텍스트의 나머지 떠나 :

$line = preg_replace('/("[^"]*")/', '<span class="a">$1</span>', $line); 

는 사실, 당신도 캡처 그룹을 사용할 필요가 없습니다합니다. 경기는 이제 인용 부분으로 구성되어 있기 때문에, 당신은 그것을 다시 삽입 $0를 사용할 수 있습니다

$line = preg_replace('/"[^"]*"/', '<span class="a">$0</span>', $line); 

편집 : @Cheery은 더 이상 적용되지 대한 그의 대답하고 내 의견을 편집했다. 나는이 대답이 아직도 어떤 가치를 더한다고 생각한다. 그래서 나는 계속 나아가 야한다.