2015-04-28 33 views
0

因此,我正在研究一个正则表达式来捕获字符串中的所有链接,这意味着wordsthat以像http,https等协议开始,以www开头的单词。或以某些特定域,“.com”,“.hr”和“.net”结尾的单词。 但不知怎的,这个正则表达式我总是返回所有以协议开始的链接,但只返回那些以特定域结尾的链接。 我在做什么错:|?非常感谢!PHP中的REGEXP捕获特定的域链接

$description='test.com test2.hr http://www.test3.hr https://test4.com test3.net'; 
$pattern = '/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]|(?:\b((?:[\w]+\.com$)|(?:[\w]+\.hr$)|(?:[\w]+\.net$)))/i'; 
preg_match_all($pattern, $description, $out); 
var_dump($out[0]); 
+0

只是为了澄清,这只是成功地在最后三个URL匹配'$说明',对吗? –

+0

是的,如果你删除最后一个网址,那么它只能匹配最后的“两个”。 –

+0

除去'$'s:https://regex101.com/r/rR6rR4/1? –

回答

1

原始正则表达式存在一些问题。首先,您应该使用条件修饰符?来处理协议。我不知道为什么你使用第二块[A-Z0-9+&@#\/%=~_|$]或为什么你在那之后使用|算子;如果有特定原因,请告诉我。最后,$只在正则表达式的最后使用它时才起作用;否则,你应该使用\Z,它匹配正则表达式中任意点的字符串结尾,尽管我不认为你想在这里匹配字符串结尾。我已经重写你想让它工作在我的思维方式下面的正则表达式:

$description='test.com test2.hr http://www.test3.hr https://test4.com test3.net trash string don\'t match test4.net'; 
$pattern = '/(?:(?:https?|ftp|file):\/\/(?:www|ftp)\.)?[-A-Z0-9+&@#\/%=~_|$?!:,.]*(\.[A-Z]+)/i'; 
preg_match_all($pattern, $description, $out); 
var_dump($out[0]); 

回报:

array(6) { 
    [0]=> 
    string(8) "test.com" 
    [1]=> 
    string(8) "test2.hr" 
    [2]=> 
    string(19) "http://www.test3.hr" 
    [3]=> 
    string(17) "https://test4.com" 
    [4]=> 
    string(9) "test3.net" 
    [5]=> 
    string(9) "test4.net" 
} 
+0

如果域名是.org? –

+0

说实话,我在某处发现了REGEX的第一部分,并且凭借我有限的知识,试图按照我的喜好对其进行编辑。 非常感谢:) –

+0

@LeoStarić如果你想更倾向于使用TLD,就像@PedroLobito建议的那样,你可以使用类似'/(?:(?: https https | | ftp | file):\/\/| www \。| ftp \。)?[ - A-Z0-9 +&@#\ /%=〜_ | $?!:,。] *(\。[AZ] +)/ i'会更好更多扩展。 –