tokeniser with unicode handling

Implement Tokeniser protocol and WordTokeniser class with NFC Unicode
normalisation, optional lowercasing, and punctuation removal.
This commit is contained in:
2025-03-09 10:06:28 +00:00
parent 494f5d0c85
commit 3e88705404

View File

@@ -0,0 +1,66 @@
"""Tokenisation utilities for text processing."""
import re
import unicodedata
from typing import Literal, Protocol
NormalisationForm = Literal["NFC", "NFD", "NFKC", "NFKD"]
class Tokeniser(Protocol):
"""Protocol for text tokenisers."""
def tokenise(self, text: str) -> list[str]: ...
class WordTokeniser:
"""
Word-level tokeniser with Unicode normalisation.
Splits text into words, with options for lowercasing and punctuation removal.
"""
def __init__(
self,
lowercase: bool = True,
remove_punctuation: bool = True,
normalisation_form: NormalisationForm = "NFC",
) -> None:
"""
Initialise the tokeniser.
Args:
lowercase: Whether to convert tokens to lowercase.
remove_punctuation: Whether to remove punctuation from tokens.
normalisation_form: Unicode normalisation form (NFC, NFD, NFKC, NFKD).
"""
self.lowercase = lowercase
self.remove_punctuation = remove_punctuation
self.normalisation_form: NormalisationForm = normalisation_form
self._punctuation_pattern = re.compile(r"[^\w\s]", re.UNICODE)
def tokenise(self, text: str) -> list[str]:
"""
Tokenise text into words.
Args:
text: The text to tokenise.
Returns:
List of word tokens. Empty list if text is empty or whitespace-only.
"""
if not text or not text.strip():
return []
normalised = unicodedata.normalize(self.normalisation_form, text)
if self.lowercase:
normalised = normalised.lower()
if self.remove_punctuation:
normalised = self._punctuation_pattern.sub(" ", normalised)
tokens = normalised.split()
return tokens