6

我想用 Python 从文本中提取 IBAN 号码。这里的挑战是,IBAN 本身可以以多种方式编写,数字之间有空格,我发现很难将其翻译成有用的正则表达式模式。

我编写了一个演示版本,它试图匹配文本中的所有德国和奥地利 IBAN 号码。

^DE([0-9a-zA-Z]\s?){20}$

我在stackoverflow上看到过类似的问题。然而,编写 IBAN 数字的不同方法的组合以及从文本中提取这些数字,使得解决我的问题变得非常困难。

希望你能帮助我!

4

3 回答 3

4
ISO地码 确认# 银行# 帐户#
德国 2a 2n 8n 10n
奥地利 2a 2n 5n 11n

注意: a - 字母(仅限字母),n - 数字(仅限数字)

所以主要区别实际上是数字的长度。这意味着您可以尝试:

\b(?:DE(?:\s*\d){20}|AT(?:\s*\d){18})\b(?!\s*\d)

请参阅在线演示


  • \b- 字边界。
  • (?:- 打开第一个非捕获组。
    • DE- 从字面上匹配大写“DE”。
    • (?:- 打开第二个非捕获组。
      • \s*\d- 零个或多个空格,最多一位数。
      • ){20}- 关闭第2个非捕获组并匹配20次。
    • |- 或者:
    • AT- 从字面上匹配大写“AT”。
    • (?:- 打开第三个非捕获组。
      • \s*\d- 零个或多个空格,最多一位数。
      • ){18}- 关闭第2个非捕获组并匹配20次。
    • )- 关闭第一个非捕获组。
  • \b- 字边界。
  • (?!\s*\d)- 负前瞻以防止任何尾随数字。

它确实表明您的奥地利 IBAN 号码无效。如果您希望提取到它们仍然有效的程度,我想您可以删除\b(?!\s*\d)

于 2021-01-15T11:28:08.743 回答
0

您可以使用

\b(?:DE|AT)(?:\s?[0-9a-zA-Z]){18}(?:(?:\s?[0-9a-zA-Z]){2})?\b

请参阅正则表达式演示详情

  • \b- 单词边界
  • (?:DE|AT)-DEAT
  • (?:\s?[0-9a-zA-Z]){18} - 出现 18 次可选空格,然后是字母数字字符
  • (?:(?:\s?[0-9a-zA-Z]){2})?- 两个序列的可选空格和字母数字字符的可选出现
  • \b- 单词边界。
于 2021-01-15T11:20:21.360 回答
0

假设您在以 self.input 作为输入字符串的类中使用此验证,请使用以下代码。虽然如果您只想验证德国和奥地利的 IBAN,我建议您从字典中删除所有其他国家:

country_dic = {
                "AL": [28, "Albania"],
                "AD": [24, "Andorra"],
                "AT": [20, "Austria"],
                "BE": [16, "Belgium"],
                "BA": [20, "Bosnia"],
                "BG": [22, "Bulgaria"],
                "HR": [21, "Croatia"],
                "CY": [28, "Cyprus"],
                "CZ": [24, "Czech Republic"],
                "DK": [18, "Denmark"],
                "EE": [20, "Estonia"],
                "FO": [18, "Faroe Islands"],
                "FI": [18, "Finland"],
                "FR": [27, "France"],
                "DE": [22, "Germany"],
                "GI": [23, "Gibraltar"],
                "GR": [27, "Greece"],
                "GL": [18, "Greenland"],
                "HU": [28, "Hungary"],
                "IS": [26, "Iceland"],
                "IE": [22, "Ireland"],
                "IL": [23, "Israel"],
                "IT": [27, "Italy"],
                "LV": [21, "Latvia"],
                "LI": [21, "Liechtenstein"],
                "LT": [20, "Lithuania"],
                "LU": [20, "Luxembourg"],
                "MK": [19, "Macedonia"],
                "MT": [31, "Malta"],
                "MU": [30, "Mauritius"],
                "MC": [27, "Monaco"],
                "ME": [22, "Montenegro"],
                "NL": [18, "Netherlands"],
                "NO": [15, "Northern Ireland"],
                "PO": [28, "Poland"],
                "PT": [25, "Portugal"],
                "RO": [24, "Romania"],
                "SM": [27, "San Marino"],
                "SA": [24, "Saudi Arabia"],
                "RS": [22, "Serbia"],
                "SK": [24, "Slovakia"],
                "SI": [19, "Slovenia"],
                "ES": [24, "Spain"],
                "SE": [24, "Sweden"],
                "CH": [21, "Switzerland"],
                "TR": [26, "Turkey"],
                "TN": [24, "Tunisia"],
                "GB": [22, "United Kingdom"]
        } # dictionary with IBAN-length per country-code
    def eval_iban(self):
        # Evaluates how many IBAN's are found in the input string
        try:
            if self.input:
                hits = 0
                for word in self.input.upper().split():
                    iban = word.strip()
                    letter_dic = {ord(d): str(i) for i, d in enumerate(
                        string.digits + string.ascii_uppercase)} # Matches letter to number for 97-proof method
                    correct_length = country_dic[iban[:2]]
                    if len(iban) == correct_length[0]: # checks whether country-code matches IBAN-length
                        if int((iban[4:] + iban[:4]).translate(letter_dic)) % 97 == 1:
                            # checks whether converted letters to numbers result in 1 when divided by 97
                            # this validates the IBAN
                            hits += 1
                return hits
            return 0
        except KeyError:
            return 0
        except Exception:
             # logging.exception('Could not evaluate IBAN')
            return 0
于 2021-06-22T12:41:35.663 回答