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