簡體   English   中英

用於驗證URL在PHP中無法正常工作的正則表達式

[英]regular expression to validate URL not working correctly in PHP

我正在使用正則表達式來驗證URL。 該表達式在JavaScript中效果很好,但是在PHP中,它給了我這個錯誤

A PHP Error was encountered

Severity: Warning

Message: preg_match() [function.preg-match]: Unknown modifier '('

Filename: home/auth.php

Line Number: 1596
A PHP Error was encountered

Severity: Warning

Message: preg_match() [function.preg-match]: Unknown modifier '('

Filename: home/auth.php

Line Number: 1601

這是我的表情

$pattern ="/^(http|https|ftp)\:\/\/www\.([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*(\.){1}((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$/";

這是PHP功能

public function valid_url($data)
{
    $data = trim($data);

    if(!$data)
    {
        return TRUE;            
    }

    $pattern ="/^(http|https|ftp)\:\/\/www\.([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*(\.){1}((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$/";
    $valid = preg_match($pattern,$data);

    if(!$valid)
    {
        $data = "http://".$data;
        $valid = preg_match($pattern,$data);
    }

    if(!$valid)
    {
        $this->form_validation->set_message('valid_url', 'Please enter a valid URL.');
        return FALSE;           
    }
    else
    {
        return TRUE;
    }       
}

我不太擅長正則表達式,因此無法弄清楚問題,請幫助我更正正則表達式。

哇,這是一個很大的表情 我發現了其中的幾個缺點,希望可以向您解釋。 讓我們分開:

$pattern ="/

這是您的第一個錯誤。 由於在URL的多個部分中使用了正斜杠,因此應使用其他定界符。 我建議使用波浪號~ ,因為URL中很少使用該波浪號。 這意味着您不必總是使用\\/來轉義正斜杠。

^(http|https|ftp)\:\/\/www\.([a-zA-Z0-9\.\-]+

該字符類包含下一個錯誤。 在字符類中,點僅表示點。 無需逃避它。 此外,將破折號放置在末尾也不需要轉義,因為它不可能表示范圍。 可以將字符類縮短為[a-zA-Z0-9.-]+

(\:[a-zA-Z0-9\.&%\$\-]+

這是下一個錯誤, & 在角色類中。 這將匹配&或a或m或a;而不僅僅是&。 您無需將其轉換為html代碼,因為這樣做將意味着匹配代碼中包含的任何字符。 並使用先前的知識,您無需轉義圓點,如果結尾處是短划線,則無需轉義。 您也不需要轉義美元符號,因為在字符類中,它僅表示美元。 請記住,在字符類中,所有的元字符,除了插入符號只是標准的字符^ ,反斜杠\\ ,右方括號] ,破折號-但這可以,如果是在年底左),不管你選擇的您的定界符,例如波浪號~ 然后,此字符類可以成為[a-zA-Z0-9.&%$-]+

)*@)*(\.){1}

部分原因可能是錯誤,也可能不是。 基本上,這里是否需要捕獲點? 如果不需要捕獲它,請不要放括號。 但是,重復中肯定存在錯誤。 {1}是完全多余的。 其中的所有內容至少必須重復一次。 這只是使代碼混亂。 上面可以縮寫為)*@)*\\.

((25[0-5]|2[0-4][0-9]|[0-1]{1}

同樣,不需要{1} 刪除它, ((25[0-5]|2[0-4][0-9]|[0-1]

[0-9]{2}|[1-9]{1}[0-9]{1}

再兩次,它變成[0-9]{2}|[1-9][0-9]
您繼續這樣做,可以縮短下一個代碼塊:

|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])

進入

|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])

並沒有令人驚訝的更好,但是一點點幫助。 下一個:

|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+

可以優化兩個字符類, |([a-zA-Z0-9-]+\\.)*[a-zA-Z0-9-]+

\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2})

這是非常嚴格的限制,但是由於某種原因,我認為您像這樣擁有它,因此我將其保留。

)(\:[0-9]+)*(/

這就是導致您出錯的原因。 您沒有逃脫正斜杠。 但是,我將保留它,因為使用其他定界符將避免這種情況,並整理您的模式。

($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$/";

現在知道我們不需要對其中的所有內容進行轉義,可以大大縮短該字符類。 它可以變成($|[a-zA-Z0-9.,?'\\\\+&%$#=~_-]+))*$/";

使用我們現在知道的所有信息,您的模式可以變得更加漂亮和易於處理。

它可以改為:

$pattern = "~^(http|https|ftp)://www\.([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])|([a-zA-Z0-9-]+\.)+(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(/($|[a-zA-Z0-9.,?'\\+&%$#=\~_-]+))*$~";

現在您有了一個較小的表達式,查找故障和進行更多自定義應該會更容易一些。

只是一個簡短的說明
我一直注意到您在某些分組的開頭使用了以下語法, (\\: :。我已刪除了反斜杠,因為冒號不需要反斜杠。但是,您是否試圖這樣做卻沒有捕獲到該組?如果是這樣,其語法為(?:

編輯:: 您還可以通過利用字符類進一步優化模式

\\ d = [0-9]
\\ w = [a-zA-Z0-9_]

在最后一個模式定界符的末尾加上i也會打開不區分大小寫的功能。 這意味着,您無需寫[a-zA-Z] ,而只需寫[az]

另外, http|https可以變成https?

因此,您的模式也可以進一步縮短:

$pattern = "~^(https?|ftp)://www\.([a-z\d.-]+(:[a-z\d.&%$-]+)*@)*((25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]\d|[1-9])\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]\d|[1-9]|0)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]\d|[1-9]|0)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]\d|\d)|([a-z\d-]+\.)+(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-z]{2}))(:\d+)*(/($|[\w.,?'\\+&%$#=\~-]+))*$~i";

我看到一個錯誤:

[0-9]+)*(/($

[0-9]+)*(\\/($

或者

[0-9]+)*(($

如果/應該是一個渲染器,那么它就不應該是。

但是說真的,您還有其他方法可以實現這一目標嗎? 此字符串確實很難解決。

為什么不使用標准的PHP函數filter_var?

http://lv.php.net/manual/ru/function.filter-var.php

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM