presidio-malaysia
Malaysian PII recognizers for Microsoft Presidio: MY_NRIC, MY_SSM, MY_PHONE,
MY_POSTCODE. The Malaysia counterpart to the Singapore and Russia recognizer
packs, with structural validation rather than bare regexes.
pip install presidio-malaysia # recognizers only
pip install "presidio-malaysia[audit]" # plus the audit/evidence layer
Use
from presidio_analyzer import AnalyzerEngine
from presidio_malaysia import all_recognizers
analyzer = AnalyzerEngine()
for recognizer in all_recognizers():
analyzer.registry.add_recognizer(recognizer)
Or, if you hold a registry rather than an engine:
from presidio_malaysia import load_malaysia_recognizers
load_malaysia_recognizers(registry)
What each recognizer actually checks
| Entity | Validation |
|---|---|
MY_NRIC |
Hyphenated and compact forms. The birth date must be a real calendar date and the place-of-birth pair an assigned code. MyKad numbers carry no check digit — anything claiming "checksum validation" for an NRIC is describing structural validation. |
MY_SSM |
New 12-digit format validated on registration year and entity-type code. Old six-to-eight-digit formats (NNNNNN-X to NNNNNNNN-X) have no internal structure and rely entirely on context words. |
MY_PHONE |
Mobile prefixes and landline area codes, with +60/60 and separators tolerated. Scoped to Malaysian numbers on purpose — Presidio's built-in PhoneRecognizer covers international ones; this exists so detections carry a MY-specific label. |
MY_POSTCODE |
Range-checked, but context-dependent by design: five bare digits carry almost no signal, so the base score is near zero and address context is what surfaces it. |
Every recognizer is tagged country_code = "MY", so recognizer.country_code() and
registry.get_country_codes() report the pack the way they report Presidio's own
country-specific recognizers. The tag is metadata, not a switch: the countries= filter
belongs to load_predefined_recognizers(), and this pack registers through
add_recognizer(), so the tag never decides whether a MY_* recognizer runs.
Context words fire on both English and Malay phrasing (nric, mykad, kad pengenalan, poskod, syarikat, telefon, …). The recognizers are regex plus
validation and do not depend on spaCy NER, which is English-only — so Malay
text is not a second-class case.
Scope: MY entities only
load_malaysia_recognizers() registers MY_* entities and nothing else. Note that
since Presidio 2.2.359 most country-specific predefined recognizers — including
SgFinRecognizer, the In* family and EsNifRecognizer — ship disabled by
default, so they will not fire out of the box either.
This matters in practice: Malaysian customer records routinely contain Singaporean identifiers. Enable them deliberately if you want them:
from presidio_analyzer.predefined_recognizers import SgFinRecognizer
registry.add_recognizer(SgFinRecognizer())
This package will not do that for you. Widening detection scope is your decision, and entities you never opted into would otherwise appear in your audit report.
One collision to know about: UK_NHS
Presidio's built-in UK_NHS recognizer is enabled by default and matches Malaysian
mobile numbers — 012-3456789 scores 1.0 as a UK NHS number, because it passes the
NHS checksum. When both fire at 1.0, Presidio's overlap resolution can pick
UK_NHS, and your audit report will then say UK_NHS for a Malaysian phone number,
with whatever operator you configured for that entity.
Two ways to deal with it, both yours to choose:
# Scope the analysis to the entities you care about
analyzer.analyze(text=text, language="en", entities=["MY_NRIC", "MY_PHONE"])
# Or drop the recognizer if you have no UK data at all
analyzer.registry.remove_recognizer("NhsRecognizer")
We do not remove it for you, for the same reason we do not enable Singapore's recognizers for you.
Precision
These recognizers report what they match. They do not guarantee they match
everything — Presidio disclaims detection completeness and so does this package.
MY_POSTCODE in particular is explicitly context-dependent and will stay quiet
without address cues. Its near-zero base score means the context enhancer's floor of
0.4 is the highest score it ever reaches — filter results at 0.6 and you will
never see a postcode.
Attribution
The NRIC place-of-birth code table follows the National Registration Department's own published tables — state codes and country codes, checked 2026-08-20. It is vendored as a static frozenset rather than taken as a dependency.
Release history: CHANGELOG.md.
Apache-2.0 licensed.
Metadata
Release files for presidio-malaysia 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| presidio_malaysia-1.0.0.tar.gz | 14.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| presidio_malaysia-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.4 kB
Release files / presidio_malaysia-1.0.0.tar.gz
| Download URL | presidio_malaysia-1.0.0.tar.gz |
|---|---|
| Size | 14.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e19380eb218d2b7fb25f3135f27f9a9773a2c32264c9a7cdf7598603cbd7a31d
|
|
BLAKE2b-256 checksum How to use checksums |
da6bc95ebf3b9885a60e44032d4100bcdd659c6d829426f061bc5246bb633664
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logRelease files / presidio_malaysia-1.0.0-py3-none-any.whl
| Download URL | presidio_malaysia-1.0.0-py3-none-any.whl |
|---|---|
| Size | 17.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
449d8f34f0030db6560052bf89030793f92f3624c1a5752bb1a27a674f7b4bf1
|
|
BLAKE2b-256 checksum How to use checksums |
6fcb2af29a56c7a5d65f22e48dea38fb367e9caf287aa39a2cf8dd92d7a06fe9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency log