2013-07-07 2 views
1

문자열에서 단어를 검색하고 링크하는 간단한 함수를 만들려고합니다. 문제는 때로는 단어 끝에 점이나 쉼표가 있기 때문에 그것을 보존하고 싶습니다. 그래서 text word.text <a href="#">word</a>.으로 변경해야하며 text <a href="#">word</a>일치를 유지하는 PHP preg_replace

이 지금까지 내 기능입니다. 당신은 아마도 당신의 검색 단어를 둘러싼 문자와 일치하는 비 캡처 그룹을 (?:...)을 사용했다

$string = "words are plenty in the world. another world and another world,comma."; 

function findWord ($string, $word, $link) { 
    $patt = "/(?:^|[^a-zA-Z])(" . preg_quote($word, '/') . ")(?:$|[^a-zA-Z])/i"; 
    return preg_replace($patt, ' <a href="'.$link.'" class="glossary-item">'.$word.'</a>$3', $string); 
} 

echo findWord ($string, "world", "#"); 

답변

1

, 그러나 그룹 (...)을 캡처하는 것처럼 다음 $3를 사용 : 나는 그것이 작동하지 않는 이유를 이해하지 않습니다.

따라서 $3은 항상 비어 있습니다. (! 그러나 또한 당신의 문자열에 $1을 대체하는 것을 잊지 마세요)

function findWord ($string, $word, $link) { 
    $patt = "/(^|[^a-zA-Z])(" . preg_quote($word, '/') . ")($|[^a-zA-Z])/i"; 
    return preg_replace($patt, '$1<a href="'.$link.'" class="glossary-item">'.$word.'</a>$3', $string); 
} 

또는 negative lookaround assertions를 사용 : 대신 그룹을 캡처 사용할 수 있습니다 중 하나

function findWord ($string, $word, $link) { 
    $patt = "/(?<![a-zA-Z])(" . preg_quote($word, '/') . ")(?![a-zA-Z])/i"; 
    return preg_replace($patt, '<a href="'.$link.'" class="glossary-item">'.$word.'</a>', $string); 
} 

나는 후자를 선호하는 것입니다.

+0

그것을 얻었습니다! 감사! –

+0

한 가지 질문입니다. 이 경우 단어 경계 수정자를 사용할 수 있습니까? return preg_replace ("% \ b $ word \ b % i", ''.$word.'', $ string); ? – sinisake

+1

@nevermind : 예,하지만 다르게 작동합니다. 예를 들어, 현재 정규식은'abc'를'_abc1'에서 추출 할 것입니다. 단어 경계가있는 정규식은 그렇지 않습니다. –