[php] URL에 대한 PHP 유효성 검사 / 정규식

URL에 대한 간단한 정규식을 찾고 있었는데, 잘 작동하는 편리한 사람이 있습니까? 나는 zend 프레임 워크 유효성 검사 클래스를 찾지 못했고 여러 구현을 보았습니다.



답변

나는 이것을 몇 가지 프로젝트에서 사용했지만 문제가 발생했다고 생각하지 않지만 철저하지 않다고 확신합니다.

$text = preg_replace(
  '#((https?|ftp)://(\S*?\.\S*?))([\s)\[\]{},;"\':<]|\.\s|$)#i',
  "'<a href=\"$1\" target=\"_blank\">$3</a>$4'",
  $text
);

마지막에 나오는 대부분의 무작위 쓰레기 http://domain.com.는 문장 과 같은 상황을 처리 하는 것입니다 (후행 마침표 일치를 피하기 위해). 나는 그것이 깨끗해질 수 있다고 확신하지만 그것이 효과가 있었기 때문에. 나는 프로젝트에서 프로젝트로 복사했습니다.


답변

filter_var()함수를 사용하여 문자열이 URL인지 여부를 확인합니다.

var_dump(filter_var('example.com', FILTER_VALIDATE_URL));

필요하지 않은 경우 정규식을 사용하는 것은 좋지 않습니다.

편집 : 조심하십시오.이 솔루션은 유니 코드 안전하지 않고 XSS 안전하지 않습니다. 복잡한 유효성 검사가 필요한 경우 다른 곳을 찾는 것이 좋습니다.


답변

PHP 매뉴얼에 따라 – parse_url해야 하지 URL을 확인하는 데 사용된다.

불행히도 filter_var('example.com', FILTER_VALIDATE_URL) 더 나은 성능을 하지 못하는 .

parse_url()및 둘 다 다음 과 filter_var()같은 잘못된 URL을 전달합니다.http://...

따라서이 경우 정규식 더 나은 방법입니다.


답변

URL이 실제로 존재하는지 알고 싶은 경우 :

function url_exist($url){//se passar a URL existe
    $c=curl_init();
    curl_setopt($c,CURLOPT_URL,$url);
    curl_setopt($c,CURLOPT_HEADER,1);//get the header
    curl_setopt($c,CURLOPT_NOBODY,1);//and *only* get the header
    curl_setopt($c,CURLOPT_RETURNTRANSFER,1);//get the response as a string from curl_exec(), rather than echoing it
    curl_setopt($c,CURLOPT_FRESH_CONNECT,1);//don't use a cached version of the url
    if(!curl_exec($c)){
        //echo $url.' inexists';
        return false;
    }else{
        //echo $url.' exists';
        return true;
    }
    //$httpcode=curl_getinfo($c,CURLINFO_HTTP_CODE);
    //return ($httpcode<400);
}


답변

John Gruber (Daring Fireball)에 따르면 :

정규식 :

(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))

preg_match ()에서 사용 :

preg_match("/(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/", $url)

다음은 확장 정규식 패턴 (주석 포함)입니다.

(?xi)
\b
(                       # Capture 1: entire matched URL
  (?:
    https?://               # http or https protocol
    |                       #   or
    www\d{0,3}[.]           # "www.", "www1.", "www2." … "www999."
    |                           #   or
    [a-z0-9.\-]+[.][a-z]{2,4}/  # looks like domain name followed by a slash
  )
  (?:                       # One or more:
    [^\s()<>]+                  # Run of non-space, non-()<>
    |                           #   or
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # balanced parens, up to 2 levels
  )+
  (?:                       # End with:
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # balanced parens, up to 2 levels
    |                               #   or
    [^\s`!()\[\]{};:'".,<>?«»“”‘’]        # not a space or one of these punct chars
  )
)

자세한 내용은
http://daringfireball.net/2010/07/improved_regex_for_matching_urls를 참조하십시오.


답변

이 경우 정규식을 사용하는 것이 현명한 일이라고 생각하지 않습니다. 모든 가능성을 일치시키는 것은 불가능하며 그렇게하더라도 URL이 단순히 존재하지 않을 가능성은 여전히 ​​있습니다.

다음은 URL이 실제로 존재하고 읽을 수 있는지 테스트하는 매우 간단한 방법입니다.

if (preg_match("#^https?://.+#", $link) and @fopen($link,"r")) echo "OK";

(없는 경우 preg_match서버의 모든 파일 이름도 확인합니다)


답변

나는 이것을 성공적으로 사용했습니다. 어디서 얻었는지 기억이 나지 않습니다.

$pattern = "/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i";