2

如果有一个文本(实际上是很多文本),其中某处是一个 ISBN,我必须找到它。

我知道:我的 ISBN-13 将以“978”开头,后跟 10 位数字。

我不知道:有多少“-”(减号)以及它们是否在正确的位置。

我的代码只会找到没有任何减号的 ISBN:

regex=r'978[0-9]{10}'
pattern = re.compile(regex, re.UNICODE)
for match in pattern.findall(mytext):
    print(match)

但是我怎样才能找到这样的 ISBN:

  • 978-123-456-789-0
  • 978-1234-567890
  • 9781234567890
  • ETC...

这可以用一个正则表达式模式吗?

谢谢!

4

6 回答 6

2

这匹配 10 个数字,并在每个数字前允许一个可选的连字符:

regex = r'978(?:-?\d){10}'
于 2013-08-14T08:52:12.433 回答
2

由于您不能有 2 个连续的连字符,并且它必须以数字结尾:

r'978(-?\d){10}'

...允许在 then 之后使用连字符978,在每个连字符后强制一个数字(不以连字符结尾),并通过使每个连字符可选来允许连续数字。

我会在 then\b之前978和之后添加{10},以确保 ISBN 与周围的文本很好地分开。

另外,我会在?:左括号之后添加,以使那些非捕获(性能稍好,也更具表现力),使其:

r'\b978(?:-?\d){10}\b'

于 2013-08-14T09:18:26.397 回答
1

-在正则表达式的模式中添加字符怎么样?这样,它将查找 (number 或-)x10 次的任意组合。

regex=r'978[0-9\-]{10}'

虽然使用起来可能更好

regex=r'978[0-9\-]+'

因为否则如果我们使用{10}and some -are found ,并不是所有的数字都会被找到。

测试

>>> import re
>>> regex=r'978[0-9\-]+'
>>> pattern = re.compile(regex, re.UNICODE)
>>> mytext="978-123-456-789-0"
>>> for match in pattern.findall(mytext):
...     print(match)
... 
978-123-456-789-0
>>> mytext="978-1234-567890"
>>> for match in pattern.findall(mytext):
...     print(match)
... 
978-1234-567890
>>> mytext="9781234567890"
>>> for match in pattern.findall(mytext):
...     print(match)
... 
9781234567890
>>> 
于 2013-08-14T08:47:37.273 回答
1

您可以尝试匹配每个数字和-字符。在这种情况下,您无法知道找到多少个字符:

regex=r'978[\d\-]+\d'
pattern = re.compile(regex, re.UNICODE)
for match in pattern.findall(mytext):
    print(match)

如果你的 ISBN 卡在其他数字或连字符之间,你会遇到一些问题,但如果它被明确分开,不用担心 :)

编辑:根据第一条评论,您可以在正则表达式的末尾添加一个额外的 \d (我已经在下面更新了我的代码),因为您知道 ISBN 以数字结尾。

于 2013-08-14T08:48:13.590 回答
0

最简单的方法应该是

regex=r'978[-0-9]{10,15}'

这将接受他们。

于 2013-08-14T08:49:15.913 回答
0

如果有人还在寻找:ISBN Detail and Contraints

简单的一个regex = r'^(978-?|979-?)?\d(-?\d){9}$'

强项isbnRegex = r'^(978-?|979-?)?\d{1,5}-?\d{1,7}-?\d{1,6}-?\d{1,3}$',在删除连字符后包括 10 和 13 的长度检查(注意:还要添加长度 = 13 的子字符串检查,即仅适用于 978 或 979,仍然需要检查一些边缘情况)

于 2018-11-26T13:55:27.923 回答