2010-05-19 5 views
1

모든 다른 유형의 링크 (상대, 절대, 루트 기준)가있는 html을 포함하는 텍스트 문자열이 있습니다. PHP의 preg_replace에 의해 실행될 수있는 정규 표현식이 필요합니다. 다른 링크를 건드리지 않고 모든 상대 링크를 루트 - 상대 링크로 대체 할 수 있습니다. 이미 루트 경로가 있습니다.상대 링크를 루트 상대 링크로 대체하는 정규식

대체 링크 :

<tag ... href="path/to_file.ext" ... > ---> <tag ... href="/basepath/path/to_file.ext" ... > 
<tag ... href="path/to_file.ext" ... /> ---> <tag ... href="/basepath/path/to_file.ext" ... /> 

손길이 닿지 않은 링크 :

<tag ... href="/any/path" ... > 
<tag ... href="/any/path" ... /> 
<tag ... href="protocol://domain.com/any/path" ... > 
<tag ... href="protocol://domain.com/any/path" ... /> 
+0

정규식이어야합니까? DOM 클래스를 사용하면 훨씬 더 정확한 결과를 얻을 수 있습니다. – webbiedave

+0

기본 DOM 판독기가 올바르게 구문 분석 할 수있을만큼 DOM이 유효하다는 보장이 없으므로 정규 표현식이어야합니다. –

답변

4

, 당신은 BASE element을 시도 할 수 있습니다. 당신이 정말로 정규 표현식을 사용하려는 경우

그렇지 않으면, (RFC 3986 참조)과 같은 상대 경로가 유형 경로 noscheme이어야한다고 생각 : 그래서

path-noscheme = segment-nz-nc *("/" segment) 
segment  = *pchar 
segment-nz-nc = 1*(unreserved/pct-encoded/sub-delims/"@") 
       ; non-zero-length segment without any colon ":" 
pchar   = unreserved/pct-encoded/sub-delims/":"/"@" 
pct-encoded = "%" HEXDIG HEXDIG 
unreserved = ALPHA/DIGIT/"-"/"."/"_"/"~" 
sub-delims = "!"/"$"/"&"/"'"/"("/")" 
      /"*"/"+"/","/";"/"=" 

URI의 시작 부분은 다음과 일치해야합니다.

^([a-zA-Z0-9-._~!$&'()*+,;[email protected]]|%[0-9a-fA-F]{2})+($|/) 

그러나 HTML을 구문 분석하기위한 적절한 HTML 파서를 사용하여 그것에서 OM. 그런 다음 DOM을 쿼리하여 href 속성을 가져 와서 위의 정규 표현식으로 값을 테스트 할 수 있습니다.

+0

베이스 태그는 href = "# test"와 같은 링크를 엉망으로 만든다는 것을 제외하면 거의 완벽하게 작동했습니다. href = "/ basepath/# test"로 바꿉니다. 위쪽에서 href = "link # test"는 작동하는 href = "/ basepath/link # test"로 바뀝니다. 앵커가 현재 URL을 모른 채 기본 클래스로 작업 할 수있는 방법이 있습니까? –

+0

위의 설명은 실제로 webkit (safari, chrome) 및 IE의 버그이며 Firefox에서는 잘 작동합니다. –

+0

@Kendall Hopkins : 내가 말했듯이 : * 모든 상대 URI가 영향을받습니다. 그리고'# test'는 상대적 URI입니다. 그리고 나는 파이어 폭스에서 base URI가''/ basepath /''/ basepath/# test'로'# test'를 해결하지 않는 버그라고 말하고 싶습니다. (파이어 폭스는 RFC 2396의 알고리즘을 사용하는 반면, 다른 사람들은 5 년 전에 RFC 3986을 폐기 한 RFC 3986 중 하나를 사용한다고 생각한다.) – Gumbo

0

나는이 함께했다 :

preg_replace('#href=["\']([^/][^\':"]*)["\']#', $root_path.'$1', $html); 

그것은 조금 너무 단순한 될 수 있습니다. 내가 본 명백한 결함은 태그 외부에있을 때 href="something"과 일치하지만 잘하면 시작할 수 있다는 것입니다.

<base href="/basepath/"> 

그러나 기본 URI를 변경하면 모든 상대 URI 그냥 상대하지 URI 경로에 영향을 미치는 있습니다 : 당신은 그냥 기본 URI를 변경하려면