PHP/Regex:检查输入的格式
我有一个输入字段,用户可以在其中写入一些链接,在提交后,我想检查此输入的正确结构 允许的结构:PHP/Regex:检查输入的格式,php,regex,Php,Regex,我有一个输入字段,用户可以在其中写入一些链接,在提交后,我想检查此输入的正确结构 允许的结构: Google: http://google.com YouTube: http://youtube.com Stackoverflow: http://stackoverflow.com/ 我的正则表达式不像我想象的那样工作 (.*)\:(\s?)(.*)\n 正则表达式应在preg_匹配函数中使用 编辑(从注释中移动): 我的代码: $input = 'Google: http://googl
Google: http://google.com
YouTube: http://youtube.com
Stackoverflow: http://stackoverflow.com/
我的正则表达式不像我想象的那样工作
(.*)\:(\s?)(.*)\n
正则表达式应在preg_匹配函数中使用
编辑(从注释中移动): 我的代码:
$input = 'Google: http://google.com
YouTube: http://youtube.com
wrong
Stackoverflow: http://stackoverflow.com/';
if (preg_match_all('/(.*?)\:\s?(.*?)$/m', $input))
{
echo 'ok';
}
else
{
echo 'no';
}
我得到“ok”。但是,由于“错误”不是正确的模式,我希望答案是“否”。你的问题有些模糊。要匹配url,您只需执行以下操作:
^[^:]+:\s*https?:\/\/[^\s]+$
# match everything except a colon, then followed by a colon
# followed by whitespaces or not
# match http/https, a colon, two forward slashes literally
# afterwards, match everything except a whitespace one or unlimited times
# anchor it to start(^) and end($) (as wanted in the comment)
请参见a。有几件事需要纠正:
- 星号运算符是贪婪的。在您的情况下,您希望它是懒惰的,所以在这两种情况下都在它后面添加一个问号李> 你可能对保持中间的分隔空间不感兴趣,所以不要在它周围放置托架;<李>
- 如果希望处理所有行,则需要使用preg_match_all而不是preg_match李>
- 除非您确定最后一行以新行结尾,否则您需要测试带美元符号的字符串的结尾李>
- 由于最后一个测试需要括号,请使用
使其不捕获,因为您对保留新行字符不感兴趣李>?:
- 有些系统在每个
之前都有\r
,因此您应该添加它,否则它会进入您的一个捕获组。或者,将\n
修饰符与$(行尾)结合使用,忘记换行符李>m
- 由于冒号也出现在URL中,您至少应该测试该冒号,否则缺少第一个冒号(在站点名称之后)将使“http”成为站点名称的一部分
$input =
"Google: http://google.com
YouTube: http://youtube.com
Stackoverflow: https://stackoverflow.com/";
$result = preg_match("/(.*?)\:\s?(\w?)\:(.*?)$/m", $input, $matches);
echo $result ? "matched!"
print_r ($matches);
产出:
Array
(
[0] => Array
(
[0] => Google: http://google.com
[1] => YouTube: http://youtube.com
[2] => Stackoverflow: https://stackoverflow.com/
)
[1] => Array
(
[0] => Google
[1] => YouTube
[2] => Stackoverflow
)
[2] => Array
(
[0] => http://google.com
[1] => http://youtube.com
[2] => https://stackoverflow.com/
)
)
第一个元素具有完整的匹配项(行),第二个元素具有第一个捕获组的匹配项,最后一个元素具有第二个捕获组的内容
请注意,以上内容不会验证URL。这是一个独立的主题。看过
编辑
如果您想确定整个输入的格式是否正确,则可以使用上面的表达式,但可以使用preg\u replace
。用空格替换所有好的行,修剪换行的最终结果,并测试是否有剩余内容:
$result = trim(preg_replace("/(.*?)\:\s?(\w*?):(.*?)$/m", "", $input));
if ($result == "") {
echo "It matches the pattern";
} else {
echo "It does not match the pattern. Offending lines:
" . $result;
}
上述情况将允许输入中出现空行。您可以通过查找不符合要求的行来实现这一点 将
'~(.*):\s?(.*)$~m'
与一起使用!预匹配
。请参阅打印“否”:
请注意,您不需要转义
:
符号。另外,我建议在末尾切换到贪心点匹配,因为这将迫使引擎一次抓取所有行,直到最后,然后在那里检查行的结尾,因此正则表达式将更有效。为了提高效率,您也可以尝试将第一个*?
替换为[^:::]*
。所以最后不要www
,总是.com
?不,它应该是可变的。我看到的唯一一件事是您需要\n
。实际上,您应该使用m
修饰符执行$
。你想让你的第一个(.*)
不贪婪,否则它将匹配url中的:
。哦,使用preg\u match\u all
而不是preg\u match
,否则你将匹配第一个而不匹配其他内容。精确的URL匹配很复杂:我不想获取URL或字符串的其他内容。我想检查一下结构是否符合要求。@Xübecks:你需要确定锚定点,看看我更新的答案。我想你理解我错了。我只想检查一下结构是否符合要求。最后,我对我的问题说了更多。你的“编辑”解决了我的问题。对不起,我说的太多了。谢谢
$input = 'Google: http://google.com
YouTube: http://youtube.com
wrong
Stackoverflow: http://stackoverflow.com/';
if (!preg_match('~(.*?):\s?(.*)$~m', $input)) {
echo 'ok';
}
else {
echo 'no';
}