2010-12-08 9 views
3

PHPで可能なURIと他のコンテンツを分離する方法は?

parse_url、filter_varなどのネイティブPHP関数を使用しようとしましたが、文字列が単一URLかTEXT(URLを含む可能性があります)であるかどうかを確認する最も簡単で最速の方法は何ですか?それらのうちのどれも期待どおりに動作しません。

UPDATE 1

もっと明確にするために、DOM要素として挿入されるスクリプトコンテンツから可能なURIを分離しようとしています。すべてのURLはSRC属性として残り、内容として残ります。例:

<script type="text/javascript" src="{$string}"></script> 
<script type="text/javascript">{$string}</script> 

UPDATE 2 可能な内容を分析して、空白文字またはセミコロンを含む文字列は、私はこのパターンが私の問題を解決できると推測する:

preg_match('/[\s]|[;]/', $string); 

それはすべての可能なjavascript/cssコードをカバーするだろうか?

+3

"URL"を定義します。彼らはいつもプロトコルプレフィックスを持っていますか?もしそうでなければ、ランダムな文字列であるURLとは何を区別するのでしょうか? httpのみ、またはftp、scp、https ...をテストしますか? username @ passwordはどうですか?ホスト名接頭辞?相対URL '/ folder/file.php'はどうですか? –

+1

技術的には、どちらの場合も有効なURLであることはご存知でしょうか?違いは、最初のものは有効なリソースになり、2番目のものはドメイン名の検証/ルックアップに失敗するということです。 – cdhowie

+0

ありがとうPekka、私はプロトコルやドメインなしでシナリオを忘れてしまった。 – Nazariy

答えて

2
$exampleData = Array(
    'http://sub-domain.my-domain.com/folder/file.php?some=param', 
    '/assets/scripts/jquery.min.js?v=1.4', 
    '<a href="/assets/scripts/jquery.min.js?v=1.4">', 
    '<a href="assets/scripts/jquery.min.js?v=1.4">', 
    'http://www.domain.com welcome text\n and some other http://www.domain.com', 
); 

foreach($exampleData as $example) 
{ 
    echo "Trying \"" . $example . "\" -> "; 

    echo (preg_match('%((http(s)?://|www\.)[^ \r\n]+|<a.+?href=(\'|")(http(s)?://|www\.|[^#])[^\4\r\n]*?\4.*?>)%i', $example)) ? 
    "Match" : "No match"; 

    echo "\r\n"; 
} 

Trying "http://sub-domain.my-domain.com/folder/file.php?some=param" -> Match 
Trying "/assets/scripts/jquery.min.js?v=1.4" -> No match 
Trying "<a href="/assets/scripts/jquery.min.js?v=1.4">" -> Match 
Trying "<a href="assets/scripts/jquery.min.js?v=1.4">" -> Match 
Trying "http://www.domain.com welcome text\n and some other http://www.domain.com" -> Match 

更新:

あなたの最後の更新を読んだ後。 HTMLを解析したい場合。以下のようなもの(HTMLを剥離)

include_once('simple_html_dom.php'); 

$dom = file_get_html('http://www.stackoverflow.com/'); 

foreach($dom->find('script') as $scriptElement) 
{ 
    if(strlen(trim($scriptElement->src)) > 0) 
    { 
     // Script with URI set 
     echo "<strong>Found script with URI</strong>"; 
     echo "<p>" . $scriptElement->src . "</p>"; 
    } 
    else 
    { 
     // Script with content 
     echo "<strong>Found script with content</strong>"; 
     echo("<p>" . nl2br(htmlspecialchars($scriptElement->innertext)) . "</p>"); 
    } 
} 

なり出力:

Found script with URI 
http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js 

Found script with URI 
http://sstatic.net/js/master.min.js?v=afc76d4deac3 

Found script with content  
var imagePath='http://sstatic.net/stackoverflow/img/'; 
var inboxUnviewedCount = -1; 

...etc 
+0

のドメインには、探していますが、私の場合、配列の3番目と4番目の要素は検証に失敗します。 – Nazariy

+0

いいえ、DOMDocumentを使用してHTMLコンテナを構築していて、2つではなくSCRIPTタグの1つのメソッドを作成しようとしています。 – Nazariy

0

filter_varあなたは、単一のURLのために欲しいものを行う必要があります。これが生じるであろう

<?php 
$safe_url = filter_var($unsafe_url, FILTER_SANITIZE_URL); 
?> 
+0

FILTER_SANITIZE_URLは$ textを有効なURLに変換します。これはアーカイブしようとしているものではありません。 – Nazariy

+0

それでは、次のようにしてください: 'if(filter_var($ url、FILTER_VALIDATE_URL))' – Buddy

+0

FILTER_VALIDATE_URLは期待どおりに機能せず、PHPの将来のリリースで修正されるでしょう。 – Nazariy

1

この関数は、渡されたテキスト場合はtrueを返します例に

http://simplehtmldom.sourceforge.net/

:のようなDOMパーサを使用しますURLです。ここで見られる正規表現に基づいています。あなたがここでそれを試すことができます

function validate_url ($url) 
{ 
    $regex = '/^(https?|ftp):\/\/'; //protocol 
    $regex .= '(([a-z0-9$_\.\+!\*\'\(\),;\?&=-]|%[0-9a-f]{2})+'; //username 
    $regex .= '(:([a-z0-9$_\.\+!\*\'\(\),;\?&=-]|%[0-9a-f]{2})+)?'; //password 
    $regex .= '@)?'; //auth requires @ 
    $regex .= '((([a-z0-9][a-z0-9-]*[a-z0-9]\.)*'; //domain segments AND 
    $regex .= '[a-z][a-z0-9-]*[a-z0-9]'; //top level domain OR 
    $regex .= '|((\d|[1-9]\d|1\d{2}|2[0-4][0-9]|25[0-5])\.){3}'; 
    $regex .= '(\d|[1-9]\d|1\d{2}|2[0-4][0-9]|25[0-5])'; //IP address 
    $regex .= ')(:\d+)?'; //port 
    $regex .= ')(((\/+([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)*'; //path 
    $regex .= '(\?([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)'; //query string 
    $regex .= '?)?)?'; //path and query string optional 
    $regex .= '(#([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)?'; //fragment 
    $regex .= '$/i'; 

    return (preg_match($regex, $url) ? true : false); 
} 

http://www.exorithm.com/algorithm/view/validate_url

EDIT応じてコメントするには、この機能は/index.phpまたはindex.phpの

function validate_url_fragment ($url) 
{ 
    $regex = '/^(((\/?([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)*'; //path 
    $regex .= '(\?([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)'; //query string 
    $regex .= '?)?)?'; //path and query string optional 
    $regex .= '(#([a-z0-9$_\.\+!\*\'\(\),;:@&=-]|%[0-9a-f]{2})*)?'; //fragment 
    $regex .= '$/i'; 

    return (preg_match($regex, $url) ? true : false); 
} 

if (validate_url_fragment($url) || validate_url($url)) { 
    //is url 
} else { 
    //not url 
} 

(ノートのようなURLフラグメントを検証します空の文字列が有効なので、特別な場合があります)

+0

それは "/index.php"のようなURLのために働くでしょうか? – Nazariy

+0

編集された編集を参照してください –

関連する問題