python isbn 13位数验证

时间:2016-06-29 23:20:16

标签: python isbn

我需要编写一个验证13位ISBN的函数。它需要从978或979开始,以一位数结束,其余部分的长度至少需要1位数。我需要一些帮助来完成这项工作,我不明白为什么它永远不会回归真实

def validate(s)
 lst = s.split("-")
 isbn= False
 if lst[0] == "978" or lst[0] == "979":
     if len(lst[1])>=1 and len(lst[2])>=1:
         if len(lst[3])==1:
            isbn= True
return isbn

4 个答案:

答案 0 :(得分:1)

你应该使用正则表达式,这正是它用于:

的原因
>>> import re
>>> def validate(isbn):
        isbn_regex = re.compile('^(978|979)-\d+-\d+-\d$')
        return isbn_regex.search(isbn) is not None

>>> print validate('978-12-12-2')
    True

注意:这符合您在上述代码中的逻辑(除非您没有检查它是否为数字)。

答案 1 :(得分:1)

ISBN-13要求13位有效。您的代码不会检查所有字符是否为数字(-分隔符除外),也不检查实际长度。此外,还需要五个部分,您可以验证校验位。

具体来说,您的代码无法返回True,因为第四个段(lst[3])会检查完全一个字符(if len(lst[3])==1:),但是,该元素通常会超过1位数。

通过PyPI可以使用python库来验证ISBN代码。以下是使用isbnlib的示例:

>>> import isbnlib
>>> isbnlib.is_isbn13('978-3-16-148410-0')
True
>>> isbnlib.is_isbn13('978-3-16-148410-5')
False
>>> isbnlib.is_isbn13('978-3-16-148410-A')
False
>>> isbnlib.is_isbn13('979-3-16-148410-9')
True

另一个重量较轻的库是pyisbn

>>> import pysisbn
>>> pyisbn.validate('979-3-16-148410-9')
True
>>> pyisbn.validate('979-3-16-148410-0')
False

除了节省您自己解析ISBN字符串的麻烦之外,使用这些库的优势在于它们提供了其他功能,例如从ISBN-13转换为ISBN-10。

答案 2 :(得分:0)

ISBN-13由五组数字组成,最后一位是校验位。这是一个功能,以确保有五个组,正好13个数字,并验证校验位。它适用于您的样品:

import re

def validate(s):
    d = re.findall(r'\d',s)
    if len(d) != 13:
        return False
    if not re.match(r'97[89](?:-\d+){3}-\d$',s):
        return False

    # The ISBN-13 check digit, which is the last digit of the ISBN, must range from 0 to 9
    # and must be such that the sum of all the thirteen digits, each multiplied by its
    # (integer) weight, alternating between 1 and 3, is a multiple of 10.
    odd = [int(x) for x in d[::2]]
    even = [int(x)*3 for x in d[1::2]]
    return (sum(odd)+sum(even)) % 10 == 0

trials = '''\
978-3-16-148410-0
978-3-16-148410
978-0-306-40615-7
978-0306-40615-7
979-11111-11-11-2
978-7654-321-12-4
977-7654-321-12-4
978-7654-321-1-41
978-7654-321-1-4
978-7654-321-122-4
'''.splitlines()

for trial in trials:
    print(validate(trial),trial)

输出:

True 978-3-16-148410-0
False 978-3-16-148410        # too few numbers and groups       
True 978-0-306-40615-7
False 978-0306-40615-7       # too few groups
True 979-11111-11-11-2
False 978-7654-321-12-4      # wrong check digit
False 977-7654-321-12-4      # didn't start with 978 or 979
False 978-7654-321-1-41      # didn't end in one digit.
False 978-7654-321-1-4       # too few digits
False 978-7654-321-122-4     # too many digits

答案 3 :(得分:0)

错误1:'def'语句末尾缺少冒号。

错误2:'return isbn'语句没有缩进;它在功能之外但应该在里面。

错误3:当lst中有超过四个元素时,检查lst [3]长度的行不会检查isbn字符串的最后一个元素。

split命令在lst中为你的第一个字符串978-3-16-148410-0创建五个元素;但是lst [3]有6位数,长度测试失败。

split命令在lst中为你的第二个字符串978-3-16-148410创建四个元素;但是lst [3]有6位数,长度测试失败。

考虑使用lst [-1]指定lst的最后一个元素,无论它包含多少元素。如果您的i / p格式正确,则o / p应该是正确的。