Stringalign
A string comparison library that adhers to the quirks of Unicode.
What is this?
Stringalign is a library for comparing strings. At its base, Stringalign takes two strings, a reference string and a predicted string, and aligns them. Based on this alignment, we can then compute many interesting performance metrics, such as the edit distance (Levenshtein), error rates and much more.
For more information, see Stringalign's extensive documentation on http://stringalign.com/.
A little example
For example, if the reference string is Banana pancakes and the predicted string is bananana pancake, then string align will align it
Reference: B--anana pancakes
Prediction: bananana pancake-
This alignment is stored as a collection of replacements, insertions, deletions and keeps, that describe what we need to do with the predicted string to make it equal to the reference string. For the string above, we get
[Replaced('B', 'b'), Inserted('a'), Inserted('n'), Kept('a'), Kept('n'), Kept('a'), Kept('n'), Kept('a'), Kept(' '), Kept('p'), Kept('a'), Kept('n'), Kept('c'), Kept('a'), Kept('k'), Kept('e'), Deleted('s')]
or, if we join consequtive the Deleted, Inserted and Replaced:
[Replaced('B', 'ban'), Kept('anana pancake'), Deleted('s')]
Based on these alignments, we can compute standard string comparison metrics such as the Levenshtein distance and character error rate. However, Stringalign also contains functions to do more in-depth analysis of the types of errors that occur when you have a whole collection of reference and predicted strings. Examples of this is: the most common character confusions, the letters most often omitted in the prediction, the letters most often incorrectly included in the prediction, etc. See our gallery of examples for more information.
What's the point?
Stringalign might sound similar to other Python libraries, like Jiwer and Levenshtein (which both use Rapidfuzz behind-the-scenes). However, what puts Stringalign apart is that it handles Unicode "correctly" and provides easy-to-use tools for going in-depth in the analysis.
Take this example:
import Levenshtein
print(Levenshtein.distance('ñ', 'ñ'))
2
What happened here?
The first 'ñ' consists of two code points: an n and a "put a tilde on the previous character" code point, while the second 'ñ' only consists of the single code point 'ñ'.
Let's try it with Stringalign instead:
from stringalign.align import levenshtein_distance
print(levenshtein_distance('ñ', 'ñ'))
0
We see the expected behaviour. By default, Stringalign will normalize your text and segment it into Unicode extended grapheme clusters before aligning. An extended grapheme cluster is essentially just what a computer should display as one letter, and while a grapheme cluster usually is just one code-point, it's not always that. Since tools like Jiwer and Levenshtein work directly on the code-points, they will miss these edge cases.
Emojis
Often, we don't need to worry about separating between code-points and grapheme clusters.
However, the moment emojis come into the picture, this changes.
Many emojis are just the single code point.
However, some are created by combining two or more other emojis --- like '🏳️🌈', which is created by combining the white-flag emoji, '🏳', a variant selector '\uFE0F', a zero width joiner '\u200D' and the rainbow emoji, '🌈'.
Because Stringalign takes care of aligning normalized grapheme clusters automatically, it will also work correctly with emoiis
import Levenshtein
from stringalign.align import levenshtein_distance
print("Levenshtein", Levenshtein.distance('🏳️🌈', '🌈'))
print("Stringalign", levenshtein_distance('🏳️🌈', '🌈'))
Levenshtein 3
stringalign 1
How does it work?
Stringalign works in a two-step process: first, the input strings are tokenized into normalised extended grapheme clusters, before they are aligned using the Needleman-Wunsch algorithm. You can customise this if you want, e.g. switching out the tokenizer with one that casefolds all extended grapheme clusters, to get a case-insensitive alignment, or words to e.g. compute the word-error rate.
We use an extension module written in Rust for two important parts of Stringalign: grouping unicode code-points into extended grapheme clusters (with the unicode_segmentation crate) and assembling the Needleman-Wunsch cost-matrix (which has O(n²) time- and memory-complexity).
Citing Stringalign
If you use Stringalign for your research, then please cite this repo. For example:
Moe, Y. M., & Roald, M. (2024). Stringalign [Computer software]. https://github.com/yngvem/stringalign
Metadata
Release files for stringalign 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 6.8 MB
Release files / stringalign-0.1.5-cp311-abi3-win_amd64.whl
| Download URL | stringalign-0.1.5-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 384.8 kB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
dd4633d5c075a81148b85a76eb0be594a8d35aebcab2952ad254d4fa795f4ff6
|
|
BLAKE2b-256 checksum How to use checksums |
7a891a60fad86f664268d8b5fa0fad782d1858fea841e7c377e9d1ac34824ec7
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-win32.whl
| Download URL | stringalign-0.1.5-cp311-abi3-win32.whl |
|---|---|
| Size | 378.8 kB |
| Tags | CPython 3.11 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
2a5f6f83d31240d41d22ebfadb77403b9809a84fa46bfd2bc46fa311a4e054f7
|
|
BLAKE2b-256 checksum How to use checksums |
74b4cc45f98f597a0a393ef628a96d469415638017feed4d42c0c37387babb7b
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-musllinux_1_2_x86_64.whl
| Download URL | stringalign-0.1.5-cp311-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 731.6 kB |
| Tags | CPython 3.11 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
e7c22c4343f88672e3b6c5adff35f6aa988a868058a49b230075b82c0121dd67
|
|
BLAKE2b-256 checksum How to use checksums |
9b0a7fbc11103301443497d5421265e67ef34ffc1ff60c90e0a9cfa5094579c7
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-musllinux_1_2_i686.whl
| Download URL | stringalign-0.1.5-cp311-abi3-musllinux_1_2_i686.whl |
|---|---|
| Size | 766.6 kB |
| Tags | CPython 3.11 Linux musl 1.2+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
77fd60c0c17684b523e6f44341222feb6f6054f00307ec3a4d00d216aa296981
|
|
BLAKE2b-256 checksum How to use checksums |
fdbcd5302102517d154361ecc02b9d264b593cc240a118dde8f4cfde592753ce
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | stringalign-0.1.5-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 532.0 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
7d779b36dcfa87bee508a00f2bdc8f82a6b1e2584922676460c4df44e32f0010
|
|
BLAKE2b-256 checksum How to use checksums |
346cc25a87f7b6d8aa4f55faaac137ce1e1fa067ace530d8ba88a11c293405e5
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
| Download URL | stringalign-0.1.5-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl |
|---|---|
| Size | 542.0 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ IBM System/390x abi3 |
|
SHA-256 checksum How to use checksums |
d23d09db4cf9f839e1bdec2a433866411f0c4fe5ab6e43a17ef446a3bde09e59
|
|
BLAKE2b-256 checksum How to use checksums |
147bedfa124ae485d487f587be8e9af9da99e175dc9578c347bcb919d922561e
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| Download URL | stringalign-0.1.5-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl |
|---|---|
| Size | 646.5 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ PowerPC 64-le abi3 |
|
SHA-256 checksum How to use checksums |
a8d40fe41473102e9cb6e9fae2c854314bd511634ef0aa5ee0a02fa2cd36bfa1
|
|
BLAKE2b-256 checksum How to use checksums |
2075bb429931852ccf9d72a789326ea97baab3dce450918f0bb36b07ba839706
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| Download URL | stringalign-0.1.5-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl |
|---|---|
| Size | 530.9 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
33082795941f1337931ccdb602f139d17fbc1e8986d5c794da30686098ac16f4
|
|
BLAKE2b-256 checksum How to use checksums |
f99c139082e3d0e2b19a52a07ad1758c924b2aaf0f5118c06caec7bf1725cee2
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | stringalign-0.1.5-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 522.3 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
0122e7b05e7e1777a6bb69c566845359cdbe993baf645a746b799be95b3e79cd
|
|
BLAKE2b-256 checksum How to use checksums |
7670a593faa7a4c3dd0be556723aa8fb700f596053ae6465f885c23a52d7eaa8
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-manylinux_2_5_i686.manylinux1_i686.whl
| Download URL | stringalign-0.1.5-cp311-abi3-manylinux_2_5_i686.manylinux1_i686.whl |
|---|---|
| Size | 548.2 kB |
| Tags | CPython 3.11 Linux glibc 2.5+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
c0395402cd51521eea8130dd0c3c6fa07f03a4ebd582cdee8e0660fce6037e6e
|
|
BLAKE2b-256 checksum How to use checksums |
35f7d2778bce05175f4bf98c9829b5648ddc32e82c7d2b781c0c2a9c14baa73d
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | stringalign-0.1.5-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 494.0 kB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
015440642a8422e5de2d0f23de4df2f91fc26bdb4971a8e0eb78724178f7571c
|
|
BLAKE2b-256 checksum How to use checksums |
54d336df44b1c3e572d816c1a87f93e3407d4b556b7f984dc988099cb46e21cd
|
| 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 17, 2026.
Transparency logRelease files / stringalign-0.1.5-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
| Download URL | stringalign-0.1.5-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl |
|---|---|
| Size | 770.5 kB |
| Tags | CPython 3.11 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
eaaa18243bc872502fc26f525f59d2f320692525af16b8f1d2b8b627108e3590
|
|
BLAKE2b-256 checksum How to use checksums |
bbfc0190b6c6a799f534757d381f2c5ae0d4a31611b31b7db1a6b7b220524edb
|
| 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 17, 2026.
Transparency logSecurity for stringalign 0.1.5
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.
Full provenance
All 12 files in this release have been uploaded with provenance metadata.
Attestation for stringalign-0.1.5-cp311-abi3-win_amd64.whl
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 17, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.