Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
## [unreleased]

### Analyzer
#### Added
- Australian bank details recognizer (`AU_BANK_DETAILS`) for detecting BSB + account-number pairs (e.g., `062-000 12345678`), disabled by default.

#### Fixed
- `PhoneRecognizer.DEFAULT_SUPPORTED_REGIONS` used `"UK"`, which is not a valid `phonenumbers` (libphonenumber) region code — region codes are ISO 3166-1 alpha-2, where the United Kingdom is `"GB"`. The `"UK"` entry was a no-op, so UK numbers in national/local format (e.g. `020 7946 0958`) were never detected by default; only international-format `+44 …` numbers matched, because they carry the country code and match under any region. Replaced `"UK"` with `"GB"`.
- Language model recognizers (`BasicLangExtractRecognizer`, `AzureOpenAILangExtractRecognizer`) configured in a recognizer registry YAML now honour `config_path` (and other recognizer-specific kwargs). Previously these entries were validated by the strict `PredefinedRecognizerConfig` schema, which has no `config_path` field and does not allow extra keys, so `config_path` was silently dropped and the recognizer fell back to its bundled default model configuration. Added a `LangExtractRecognizerConfig` model (`extra="allow"`) and registered both recognizer class names in `CONFIG_MODEL_MAP`.
Expand Down
1 change: 1 addition & 0 deletions docs/supported_entities.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ For more information, refer to the [adding new recognizers documentation](analyz
|AU_ACN| An Australian Company Number is a unique nine-digit number issued by the Australian Securities and Investments Commission to every company registered under the Commonwealth Corporations Act 2001 as an identifier. | Pattern match, context, and checksum |
|AU_TFN| The tax file number (TFN) is a unique identifier issued by the Australian Taxation Office to each taxpaying entity | Pattern match, context, and checksum |
|AU_MEDICARE| Medicare number is a unique identifier issued by Australian Government that enables the cardholder to receive a rebates of medical expenses under Australia's Medicare system| Pattern match, context, and checksum |
|AU_BANK_DETAILS| Australian bank details where both BSB (6 digits) and account number (6-10 digits) are present together (for example `062-000 12345678`).| Pattern match, context, and structural validation |

### India
| FieldType | Description |Detection Method|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ recognizers:
enabled: false
country_code: au

- name: AuBankDetailsRecognizer
supported_languages:
- en
type: predefined
enabled: false
country_code: au

- name: NgNinRecognizer
supported_languages:
- en
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

from .country_specific.australia.au_abn_recognizer import AuAbnRecognizer
from .country_specific.australia.au_acn_recognizer import AuAcnRecognizer
from .country_specific.australia.au_bank_details_recognizer import (
AuBankDetailsRecognizer,
)
from .country_specific.australia.au_medicare_recognizer import AuMedicareRecognizer
from .country_specific.australia.au_tfn_recognizer import AuTfnRecognizer

Expand Down Expand Up @@ -211,6 +214,7 @@
"NLP_RECOGNIZERS",
"AuAbnRecognizer",
"AuAcnRecognizer",
"AuBankDetailsRecognizer",
"AuTfnRecognizer",
"AuMedicareRecognizer",
"TransformersRecognizer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

from .au_abn_recognizer import AuAbnRecognizer
from .au_acn_recognizer import AuAcnRecognizer
from .au_bank_details_recognizer import AuBankDetailsRecognizer
from .au_medicare_recognizer import AuMedicareRecognizer
from .au_tfn_recognizer import AuTfnRecognizer

__all__ = [
"AuAbnRecognizer",
"AuAcnRecognizer",
"AuBankDetailsRecognizer",
"AuMedicareRecognizer",
"AuTfnRecognizer",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import re
from typing import List, Optional

from presidio_analyzer import Pattern, PatternRecognizer


class AuBankDetailsRecognizer(PatternRecognizer):
"""
Recognises Australian bank details (BSB and account number).

This recognizer detects Australian bank details where both:
- a BSB (Bank State Branch) number, and
- an account number
are present together in the same token sequence.

Typical formats include:
- BSB 062-000 Account 12345678
- 062-000 12345678

Reference:
- https://en.wikipedia.org/wiki/Bank_state_branch

:param patterns: List of patterns to be used by this recognizer
:param context: List of context words to increase confidence in detection
:param supported_language: Language this recognizer supports
:param supported_entity: The entity this recognizer can detect
:param name: Name of recognizer
"""

COUNTRY_CODE = "au"

PATTERNS = [
Pattern(
"AU bank details (High)",
r"\b(?:bsb)[^\S\r\n]*[:\-]?[^\S\r\n]*\d{3}[- ]?\d{3}[^\S\r\n]*(?:[,;][^\S\r\n]*)?(?:account(?:[^\S\r\n]*number)?|acct|a/c|acc(?:ount)?)[^\S\r\n]*[:\-]?[^\S\r\n]*\d{6,10}\b", # noqa: E501
0.5,
),
Pattern(
"AU bank details (Medium)",
r"\b\d{3}[- ]?\d{3}[^\S\r\n]+\d{6,10}\b",
0.2,
),
]

CONTEXT = [
"bsb",
"bank",
"account",
"account number",
"bank account",
]

def __init__(
self,
patterns: Optional[List[Pattern]] = None,
context: Optional[List[str]] = None,
supported_language: str = "en",
supported_entity: str = "AU_BANK_DETAILS",
name: Optional[str] = None,
):
patterns = patterns if patterns else self.PATTERNS
context = context if context else self.CONTEXT
super().__init__(
supported_entity=supported_entity,
patterns=patterns,
context=context,
supported_language=supported_language,
name=name,
)

def validate_result(self, pattern_text: str) -> bool:
"""
Validate structural constraints for AU bank details.

:param pattern_text: Matched text from the regex engine.
:return: True when text contains a plausible BSB + account pair.
"""
digits = re.sub(r"\D", "", pattern_text)
if len(digits) < 12 or len(digits) > 16:
return False

bsb = digits[:6]
account = digits[6:]
if len(account) < 6 or len(account) > 10:
return False

# Basic plausibility guard to reduce obvious false positives.
return bsb != "000000" and account != "0" * len(account)
53 changes: 53 additions & 0 deletions presidio-analyzer/tests/test_au_bank_details_recognizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import pytest

from tests import assert_result_within_score_range
from presidio_analyzer.predefined_recognizers import AuBankDetailsRecognizer


@pytest.fixture(scope="module")
def recognizer():
return AuBankDetailsRecognizer()


@pytest.fixture(scope="module")
def entities():
return ["AU_BANK_DETAILS"]


@pytest.mark.parametrize(
"text, expected_len, expected_positions, expected_score_ranges",
[
# Valid BSB + account formats.
("062-000 12345678", 1, ((0, 16),), ((1.0, 1.0),),),
("062 000 123456", 1, ((0, 14),), ((1.0, 1.0),),),
("BSB: 062-000 Account: 12345678", 1, ((0, 30),), ((1.0, 1.0),),),
# Invalid account length.
("062-000 12345", 0, (), (),),
# Invalid structural values.
("000-000 12345678", 0, (), (),),
("062-000 000000", 0, (), (),),
# Invalid formats.
("06200012345678", 0, (), (),),
("123 456\n789012", 0, (), (),),
("BSB: 062-000\nAccount: 12345678", 0, (), (),),
],
)
def test_when_all_au_bank_details_then_succeed(
text,
expected_len,
expected_positions,
expected_score_ranges,
recognizer,
entities,
max_score,
):
results = recognizer.analyze(text, entities)
assert len(results) == expected_len
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
results, expected_positions, expected_score_ranges
):
if fn_score == "max":
fn_score = max_score
assert_result_within_score_range(
res, entities[0], st_pos, fn_pos, st_score, fn_score
)