Surgical, occurrence-based word manipulation for strings and files
Project description
wordscalpel 🔪
Surgical, occurrence-based word manipulation for strings and files.
Designed for large-scale, structure-safe text transformations with streaming support.
Log sanitization, document redaction, and content pipelines often need precise word-level control that Python's standard library doesn't provide. wordscalpel solves that permanently.
⚡️ Why wordscalpel?
Standard Python .replace() and Regex are blind—they either replace everything, the first occurrence, or require complex error-prone patterns. wordscalpel allows you to target exact integer occurrences or ranges, swap terms cleanly, and stream 10GB files without breaking a sweat.
🆚 How it compares
| Feature | wordscalpel |
Standard .replace() |
Regex (re.sub) |
sed (CLI) |
|---|---|---|---|---|
| Replace $N$th occurrence | ✅ Native | ❌ No | ⚠️ Complex logic | ⚠️ Awkward syntax |
| Replace occurrence ranges | ✅ Native | ❌ No | ❌ No | ⚠️ Very hard |
| Simultaneous A↔B Swap | ✅ Native | ❌ Breaks on overlap | ⚠️ Custom functions | ⚠️ Difficult |
| Smart Space Cleanup | ✅ Native | ❌ No | ⚠️ Manual patterns | ⚠️ Manual patterns |
| O(1) Memory Streaming | ✅ Native | ❌ Loads entire string | ❌ Loads entire string | ✅ Yes |
| Indentation Safe | ✅ Yes | ❌ Blind wipe | ⚠️ Manual Lookbehinds | ⚠️ Blind wipe |
🎯 Core Capabilities
- Intelligent Space Normalization: Safely swallows extra bounding spaces upon deletion to preserve code alignments, without breaking text structure or indentation.
- O(1) Streaming Engine: Never loads massive
.logor.sqlfiles into memory; files are operated on dynamically chunk-by-chunk for unmatched speed. - Perfect Safety: Synchronous word-swapping absolutely prevents "double-replace" collision traps.
- Zero Dependencies: Built entirely using the Python standard library.
🛡️ Structured Capability Matrix
wordscalpel handles formats with precise awareness of structural memory scale constraints:
| Format | Streaming Engine | Memory Safe | Notes |
|---|---|---|---|
| Text Files (.log, .txt) | ✅ Yes | ✅ Yes | O(1) Memory row-by-row stream. Perfect for standard massive files. |
| CSV | ✅ Yes | ✅ Yes | O(1) streaming using standard Python csv module row-by-row parsing. |
| JSON | ❌ No | ⚠️ Varies | Uses json.loads. Safe for metadata chunks, but loads structure into memory. |
| Python Objects | N/A | ⚠️ Varies | Safely recurses through loaded active memory objects. |
📦 Installation
pip install wordscalpel
💻 CLI Tools
Use the wordscalpel binary right from your terminal without opening Python!
# 1. Remove the EXACT 2nd occurrence of 'error' from a log
wordscalpel remove --word "error" --n 2 --file server.log --output out.log
# 2. Re-write the first 5 occurrences
wordscalpel replace --word "DEBUG" --with "INFO" --range 1 5 --file server.log
# 3. Swap variables simultaneously everywhere
wordscalpel swap --word "cat" --swap-with "dog" --file input.txt
# 4. Extract instances with beautiful surrounding context arrays (-c chars)
wordscalpel find --word "Exception" --context 20 --file server.log
🐍 Python API (v2.0)
Using the newly refined minimal API, text operations are universally effortless.
import wordscalpel as ws
text = "the cat sat on the mat near the hat"
# 🔍 Inspection
ws.count(text, "the") # → 3
ws.find(text, "the", context=10) # → Metadata and surrounding substrings
# ✂️ Smart Removal (Intelligently drops adjacent spaces natively)
ws.remove(text, "the", n=2) # → "the cat sat on mat near the hat"
ws.remove(text, "the", n=(1, 2)) # Remove 1st and 2nd
# 🔁 Swaps & Replacements
ws.replace(text, "the", "a", n=2) # → "the cat sat on a mat near the hat"
ws.swap("cat chased dog", "cat", "dog") # → "dog chased cat"
Advanced Control (Space Targeting)
# Un-normalized raw mode (protects exact consecutive space-counts)
ws.remove("a b a c", "a", normalize=False) # → " b c "
📄 File Stream Operations
Every core function has a file_* counterpart that safely mutates massive files on disk using efficient O(1) memory pipelines.
from wordscalpel.file_ops import file_count, file_remove, file_replace, file_swap
# ONE KILLER DEMO: Safely scrub 15,000 deep targets off a 5GB
# streaming file without loading it to RAM or affecting JSON brackets
file_remove("massive_production_export.log", "PASSWORD_HASH", n=(10000, 25000))
# Change specific variable definitions safely inline
file_replace("input.py", "deprecated_var", "new_var", n=2)
🛡️ Error Safety (Exceptions)
Strict adherence to safe typing and predictable error catching:
from wordscalpel.exceptions import WordscalpelError, OccurrenceNotFoundError
try:
ws.remove("hello world", "hello", n=5)
except OccurrenceNotFoundError as e:
print(e) # "Occurrence 5 of 'hello' not found. Total occurrences found: 1"
Running Tests
Developed via TDD. 100% Core coverage.
pip install pytest
pytest tests/ -v
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wordscalpel-2.0.4.tar.gz.
File metadata
- Download URL: wordscalpel-2.0.4.tar.gz
- Upload date:
- Size: 21.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73fc870cf75a9031fff8e885bbbf9b7ace737465fd0cd3691bd1c78d6a5e384f
|
|
| MD5 |
83bb14a8f8f760ec124c3a995527c56c
|
|
| BLAKE2b-256 |
4f37a42a8e8a4454869e75d418d5bd560d6b4a5faebf5d30f03f94d13b87d157
|
File details
Details for the file wordscalpel-2.0.4-py3-none-any.whl.
File metadata
- Download URL: wordscalpel-2.0.4-py3-none-any.whl
- Upload date:
- Size: 18.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b596b29de7baf8679f990ea875f83b82b4c68e16f5165060ac2ea3469960a701
|
|
| MD5 |
2a571ed3004b1010510cfd2361070c52
|
|
| BLAKE2b-256 |
970828be13fac8a52629403fc57ba26dcf82a1c3934e36c26c30803614e33256
|