Metadata-Version: 2.4
Name: melon-browser
Version: 0.1.0
Summary: Readable and optimized string-matching algorithms and a fast keyword processor.
Author-email: alvations <alvations@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/alvations/melon-strings
Project-URL: Repository, https://github.com/alvations/melon-strings
Keywords: string-matching,aho-corasick,keyword-extraction,flashtext,boyer-moore,knuth-morris-pratt,text-processing,nlp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: C++
Classifier: Topic :: Text Processing
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Provides-Extra: bench
Requires-Dist: flashtext; extra == "bench"
Dynamic: license-file

# melon-strings 🍈

**Readable *and* fast string matching for Python.**

`melon-strings` is two libraries in one package:

1. **`melon.pure` — the explainable half.** Dependency-free, heavily commented
   reference implementations of the entire
   [Charras–Lecroq "Exact String Matching Algorithms"](http://www-igm.univ-mlv.fr/~lecroq/string/)
   catalog (35 algorithms), plus a classic Aho–Corasick automaton. Written to be
   *read* — every module explains the idea and the complexity in plain English.
2. **`melon.fast` — the optimized half.** A hand-written C++ trie engine (built
   with [pybind11](https://github.com/pybind/pybind11)) powering a keyword
   extractor/replacer that matches or beats
   [`flashtext`](https://github.com/vi3k6i5/flashtext), with an automatic
   pure-Python fallback when the extension isn't compiled.

Copyright 2026 alvations. Licensed under **Apache-2.0**.

---

## Install

```bash
pip install melon-strings          # builds the C++ backend if a compiler exists
```

From a checkout:

```bash
pip install -e .
```

If no C++ compiler is available the install still succeeds and the library
transparently uses the pure-Python engine (`melon.fast.is_native_available()`
tells you which backend is active).

---

## Keyword extraction & replacement (the flashtext-style API)

```python
from melon import KeywordProcessor          # auto-selects the C++ backend

kp = KeywordProcessor()
kp.add_keyword("New York", "NYC")           # keyword -> clean name
kp.add_keyword("machine learning")

kp.extract_keywords("machine learning jobs in New York")
# ['machine learning', 'NYC']

kp.replace_keywords("machine learning jobs in New York")
# 'machine learning jobs in NYC'

kp.extract_keywords("the cat sat", span_info=True)
# [('cat', 4, 7)]         # exact character spans
```

### What it does that flashtext does — and more

| Capability | flashtext | melon-strings |
|---|:-:|:-:|
| Trie-based `O(n)` extraction & replacement | ✅ | ✅ |
| `add_keyword` / `remove_keyword` / from list / from dict | ✅ | ✅ |
| Case-insensitive matching, clean-name mapping | ✅ | ✅ |
| `span_info` positions | ✅ | ✅ (+`extract_keywords_with_span`) |
| Dict-like API (`kp[k]=v`, `k in kp`, `del kp[k]`, `len`, `iter`) | partial | ✅ |
| Configurable word boundaries | ✅ | ✅ |
| **Raw substring mode** (`word_boundary=False`) | ❌ | ✅ |
| **Unicode word boundaries** (`unicode=True`) | ❌ | ✅ |
| **Replacement counts** (`return_count=True`) | ❌ | ✅ |
| **C++ backend + identical pure fallback** | ❌ | ✅ |

```python
# One-ups
kp.replace_keywords("cat cat", return_count=True)     # ('cat cat', 2)
KeywordProcessor(word_boundary=False)                 # match substrings anywhere
KeywordProcessor(unicode=True)                        # Unicode-aware boundaries
```

Pick a backend explicitly if you like:

```python
from melon.pure.keyword import KeywordProcessor as PureKP   # always pure Python
from melon.fast import KeywordProcessor as FastKP           # C++ (falls back to pure)
```

---

## The exact-matching algorithm zoo (`melon.pure.exact`)

Every algorithm exposes the *same* interface, so they're drop-in interchangeable:

```python
from melon.pure.exact import boyer_moore, ALGORITHMS

boyer_moore.search("abracadabra", "abra")     # [0, 7]  -> all start indices
list(boyer_moore.finditer("abracadabra", "abra"))  # lazy iterator

# Iterate over the whole catalog:
for name, module in ALGORITHMS.items():
    assert module.search("banana", "ana") == [1, 3]
```

All 35 algorithms from the Charras–Lecroq catalog are implemented and validated
against a brute-force oracle on thousands of random cases. See
[`docs/algorithms.md`](docs/algorithms.md) for the full annotated list.

```python
from melon.pure.multi import AhoCorasick     # multi-pattern, all occurrences
ac = AhoCorasick(["he", "she", "his", "hers"])
[(m.start, m.end, m.keyword) for m in ac.finditer("ushers")]
# [(1, 4, 'she'), (2, 4, 'he'), (2, 6, 'hers')]
```

---

## Command line

```bash
melon extract --keywords keywords.txt document.txt      # or: python -m melon ...
melon extract --keywords keywords.txt --spans doc.txt   # with char offsets
melon replace --keywords map.txt --count doc.txt        # key=clean lines
melon search  --algorithm boyer_moore --pattern cat doc.txt
melon algorithms                                        # list every algorithm
```

---

## Development

```bash
pip install -e ".[test]"
python scripts/validate.py           # brute-force oracle over every algorithm
pytest -q                            # full test suite
pytest --doctest-modules src/melon   # the docstring examples are runnable
python benchmarks/benchmark.py       # pure vs C++ vs flashtext vs regex
```

---

## License

Apache License 2.0 — see [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE).
The `melon.pure` algorithms are educational reimplementations based on Charras &
Lecroq's descriptions; the keyword API is inspired by `flashtext` / `flashtext2`.
