Skip to main content

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)

Source distribution for presidio-malaysia 1.0.0
File Size Uploaded
presidio_malaysia-1.0.0.tar.gz 14.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for presidio-malaysia 1.0.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page