mk_*_*_89 20 php regex validation isbn
我有一个If-else语句,它检查字符串以查看是否有ISBN-10或ISBN-13(书籍ID).
我面临的问题是在ISBN-10检查之前发生的ISBN-10检查,ISBN-10检查将匹配10个字符或更多的任何内容,因此可能会将ISBN-13误认为是ISBN-10.
这是代码......
$str = "ISBN:9780113411436";
if(preg_match("/\d{9}(?:\d|X)/", $str, $matches)){
echo "ISBN-10 FOUND\n";
//isbn returned will be 9780113411
return 0;
}
else if(preg_match("/\d{12}(?:\d|X)/", $str, $matches)){
echo "ISBN-13 FOUND\n";
//isbn returned will be 9780113411436
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我该如何确保避免此问题?
cry*_*c ツ 40
你真的只需要一个正则表达式.然后进行更有效的strlen()检查以查看哪一个匹配.以下内容将匹配带或不带连字符的字符串中的ISBN-10和ISBN-13值,并且可选地以字符串开头ISBN:,ISBN:(space)或者ISBN(space).
function findIsbn($str)
{
$regex = '/\b(?:ISBN(?:: ?| ))?((?:97[89])?\d{9}[\dx])\b/i';
if (preg_match($regex, str_replace('-', '', $str), $matches)) {
return (10 === strlen($matches[1]))
? 1 // ISBN-10
: 2; // ISBN-13
}
return false; // No valid ISBN found
}
var_dump(findIsbn('ISBN:0-306-40615-2')); // return 1
var_dump(findIsbn('0-306-40615-2')); // return 1
var_dump(findIsbn('ISBN:0306406152')); // return 1
var_dump(findIsbn('0306406152')); // return 1
var_dump(findIsbn('ISBN:979-1-090-63607-1')); // return 2
var_dump(findIsbn('979-1-090-63607-1')); // return 2
var_dump(findIsbn('ISBN:9791090636071')); // return 2
var_dump(findIsbn('9791090636071')); // return 2
var_dump(findIsbn('ISBN:97811')); // return false
Run Code Online (Sandbox Code Playgroud)
这将搜索提供的字符串,以查看它是否包含可能的ISBN-10值(返回1)或ISBN-13值(返回2).如果没有,它将返回false.
见上面的DEMO.
对于严格验证,ISBN 的维基百科文章具有ISBN-10和ISBN-13的一些PHP验证功能.下面是复制,整理和修改的示例,以用于上述函数的略微修改版本.
将返回块更改为:
return (10 === strlen($matches[1]))
? isValidIsbn10($matches[1]) // ISBN-10
: isValidIsbn13($matches[1]); // ISBN-13
Run Code Online (Sandbox Code Playgroud)
验证ISBN-10:
function isValidIsbn10($isbn)
{
$check = 0;
for ($i = 0; $i < 10; $i++) {
if ('x' === strtolower($isbn[$i])) {
$check += 10 * (10 - $i);
} elseif (is_numeric($isbn[$i])) {
$check += (int)$isbn[$i] * (10 - $i);
} else {
return false;
}
}
return (0 === ($check % 11)) ? 1 : false;
}
Run Code Online (Sandbox Code Playgroud)
验证ISBN-13:
function isValidIsbn13($isbn)
{
$check = 0;
for ($i = 0; $i < 13; $i += 2) {
$check += (int)$isbn[$i];
}
for ($i = 1; $i < 12; $i += 2) {
$check += 3 * $isbn[$i];
}
return (0 === ($check % 10)) ? 2 : false;
}
Run Code Online (Sandbox Code Playgroud)
见上面的DEMO.