简体   繁体   English

python isbn 13位数验证

[英]python isbn 13 digit validate

I need to write a function that validates a 13 digit ISBN. 我需要编写一个验证13位ISBN的函数。 It needs to start with 978 or 979, end with a single digit, and the remaining sections need to be at least 1 digit in length. 它必须以978或979开头,以一位数字结尾,其余部分的长度至少应为1位数字。 I need some help to make this work, I don't understand why it never returns true 我需要一些帮助来完成这项工作,我不明白为什么它永远不会返回true

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

You should use regular expression and this is exactly why it is used for: 您应该使用正则表达式,这就是为什么将其用于:

>>> 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

Note: This works as per your logic in the above code(except for you didn't check whether it's a digit). 注意:这可以按照您在上述代码中的逻辑进行工作(除非您不检查它是否为数字)。

ISBN-13 requires 13 digits to be valid. ISBN-13要求13位数字有效。 Your code does not check that all characters are digits (excluding the - separator), nor does it check the actual length. 您的代码不会检查所有字符是否都是数字( -分隔符除外),也不会检查实际长度。 Also, five parts are required, and you could be verifying the check digit. 另外,还需要五个部分,您可能正在验证校验位。

Specifically your code fails to ever return True because the fourth segment ( lst[3] ) checks for exactly one character ( if len(lst[3])==1: ), however, that element will typically be longer than 1 digit. 具体代码无法再回到True因为第四区段( lst[3]检查一个字符( if len(lst[3])==1:但是,该元素将典型地长于1个位数。

There are python libraries available via PyPI that can validate ISBN codes. 通过PyPI提供的python库可以验证ISBN代码。 Here's an example using isbnlib : 这是使用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

Another, lighter weight library is pyisbn : 另一个重量较轻的库是pyisbn

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

The advantage of using these libraries, other than saving you the hassle of parsing ISBN strings yourself, is that they offer additional functionality such as converting from ISBN-13 to ISBN-10. 使用这些库的好处在于,它们可以提供其他功能,例如从ISBN-13转换为ISBN-10,除了为您自己节省解析ISBN字符串的麻烦之外,还提供了其他功能。

An ISBN-13 consists of five groups of numbers and the last digit is a check digit. ISBN-13由五组数字组成,最后一位是校验位。 Here's a function to make sure there are five groups, exactly 13 digits, and validates the check digit. 这是一个功能,用于确保有五个组,正好是13位数字,并验证校验位。 It works with your samples: 它适用于您的样本:

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)

Output: 输出:

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

Error 1: Missing a colon at end of the 'def' statement. 错误1:在'def'语句末尾缺少一个冒号。

Error 2: The 'return isbn' statement is not indented; 错误2:未将'return isbn'语句缩进; it is outside the function but should be inside. 它在函数外部,但应该在内部。

Error 3: The line checking the length of lst[3] does not check the last element of the isbn string when there are more than four elements in lst. 错误3:当lst中有四个以上元素时,检查lst [3]长度的行未检查isbn字符串的最后一个元素。

The split command creates five elements in lst for your first string, 978-3-16-148410-0; split命令首先为您的第一个字符串978-3-16-148410-0创建五个元素; but lst[3] has 6 digits, and the length test fails. 但是lst [3]有6位数字,并且长度测试失败。

The split command creates four elements in lst for your second string, 978-3-16-148410; split命令首先在您的第二个字符串978-3-16-148410中创建四个元素; but lst[3] has 6 digits, and the length test fails. 但是lst [3]有6位数字,并且长度测试失败。

Consider using lst[-1] to specify the last element of lst, regardless of how many elements it contains. 考虑使用lst [-1]指定lst的最后一个元素,无论它包含多少个元素。 If your i/p is formatted correctly, the o/p should be correct. 如果您的i / p格式正确,则o / p应该正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM