I have an If-else statement which checks a string to see whether there is an ISBN-10 or ISBN-13 (book ID).
The problem I am facing is with the ISBN-10 check which occurs before the ISBN-13 check, the ISBN-10 check will match anything with 10 characters or more and so may mistake an ISBN-13 for an ISBN-10.
here is the code...
$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;
}
How do I make sure I avoid this problem?
You really only need one regex for this. Then do a more efficient
strlen()
check to see which one was matched. The following will match ISBN-10 and ISBN-13 values within a string with or without hyphens, and optionally preceded by the stringISBN:
,ISBN:(space)
orISBN(space)
.Finding ISBNs :
This will search a provided string to see if it contains a possible ISBN-10 value (returns
1
) or an ISBN-13 value (returns2
). If it does not it will returnfalse
.See DEMO of above.
Validating ISBNs :
For strict validation the Wikipedia article for ISBN has some PHP validation functions for ISBN-10 and ISBN-13. Below are those examples copied, tidied up and modified to be used against a slightly modified version of the above function.
Change the return block to this:
Validate ISBN-10:
Validate ISBN-13:
See DEMO of above.
Use
^
and$
to match beginning and end of string. By using the string delimiters, the order in which you test the 10 or the 13-digit codes will not matter.10 digits
13 digits
Note: According to http://en.wikipedia.org/wiki/International_Standard_Book_Number, it appears as though ISBNs can have a
-
in them as well. But based on the$str
you're using, it looks like you've removed the hyphens before checking for 10 or 13 digits.Additional note: Because the last digit of the ISBN is used as a sort of checksum for the prior digits, regular expressions alone cannot validate that the ISBN is a valid one. It can only check for 10 or 13-digit formats.
Output
Switch the order of the
if else
block, also strip all whitespace, colons, and hyphens from your ISBN:Put the ISBN-13 check before the ISBN-10 check? This is assuming that you want to match them as a part of any string, that is (your example has an extra "ISBN:" at the start so matching anywhere in a string seems to be a requirement of some sort)