PHPackages                             iserter/php-ai-text-sanitizer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. iserter/php-ai-text-sanitizer

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

iserter/php-ai-text-sanitizer
=============================

A dependency-free PHP library that detects and removes invisible watermarks and normalizes tell-tale typography from AI-generated text.

v1.0.0(1mo ago)07MITPHPPHP ^8.1CI passing

Since Jul 4Pushed 1mo agoCompare

[ Source](https://github.com/iSerter/php-ai-text-sanitizer)[ Packagist](https://packagist.org/packages/iserter/php-ai-text-sanitizer)[ RSS](/packages/iserter-php-ai-text-sanitizer/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (3)Used By (0)

php-ai-text-sanitizer
=====================

[](#php-ai-text-sanitizer)

A small, dependency-free PHP library that **detects and removes invisible watermarks** — and other tell-tale characters — that AI providers leave in generated text.

Large language models routinely emit characters that render as nothing but survive copy/paste: zero-width spaces and joiners, Unicode *tag* characters (`U+E0000–E007F`) and variation selectors used for steganographic watermarking, bidirectional controls, and unusual spaces such as the narrow no-break space (`U+202F`). This library strips them, and can optionally normalize the visible typography (smart quotes, dashes, ellipses) that also signals machine authorship.

- **Zero dependencies.** Pure PHP 8.1+, PCRE with the `/u` modifier, and `mbstring`.
- **Framework-agnostic.** Drop it into any PSR-4 project and adjust the namespace.
- **Detect *and* clean.** Use it as a filter, or as a "was this AI-watermarked?" check.

Install
-------

[](#install)

```
composer require iserter/php-ai-text-sanitizer
```

Usage
-----

[](#usage)

### One-liner

[](#one-liner)

```
use iSerter\AiTextSanitizer\AITextSanitizer;

$clean = AITextSanitizer::clean_text($aiOutput);
```

### Configured instance

[](#configured-instance)

```
$sanitizer = new AITextSanitizer([
    'normalize_smart_quotes' => true,
    'normalize_dashes'       => true,
]);

$clean = $sanitizer->sanitize($aiOutput);
```

### Clean with a report of what changed

[](#clean-with-a-report-of-what-changed)

```
$result = $sanitizer->clean($aiOutput);

if ($result->wasModified()) {
    error_log($result->getReport()->summary());
}

echo $result->getText();
```

### Detect only (don't modify)

[](#detect-only-dont-modify)

```
$report = $sanitizer->detect($aiOutput);

if ($report->hasWatermarks()) {
    foreach ($report->getFindings() as $f) {
        printf("%s %s [%s] x%d\n", $f->notation(), $f->name, $f->category, $f->count);
    }
}
```

Options
-------

[](#options)

OptionDefaultEffect`remove_zero_width``true`Remove ZWSP, ZWNJ, ZWJ, word joiner, BOM (`U+200B–200D`, `U+2060`, `U+FEFF`).`remove_bidi``true`Remove bidirectional marks/controls (`U+200E/200F`, `U+202A–202E`, `U+2066–2069`, `U+061C`).`remove_invisible_math``true`Remove invisible math operators (`U+2061–2064`).`remove_variation_selectors``true`Remove variation selectors (`U+FE00–FE0F`, `U+E0100–E01EF`).`remove_tag_chars``true`Remove the Unicode Tags block (`U+E0000–E007F`).`remove_format_chars``true`Remove soft hyphen, CGJ, Hangul fillers, interlinear annotations, etc.`remove_braille_blank``true`Remove `U+2800` BRAILLE PATTERN BLANK.`strip_control``true`Remove stray C0/C1 control characters (keeps TAB, LF, CR).`keep_emoji``true`Preserve ZWJ and variation selectors when they are part of a valid emoji sequence.`remove_citations``false`Remove AI-generated citations like `(oaicite:5){index=5}` or `【13†source】`.`normalize_homoglyphs``false`Apply NFKC normalization to neutralize visually identical homoglyphs (requires `ext-intl`).`normalize_spaces``true`Fold unusual spaces (NBSP, thin space, ideographic space, …) to `U+0020`.`normalize_line_separators``true``U+2028` → `\n`, `U+2029` → `\n\n`.`normalize_smart_quotes``false`Curly/angle quotes → straight `'` and `"`.`normalize_dashes``false`Dashes and minus (`U+2010–2015`, `U+2212`) → `-`.`normalize_ellipsis``false``U+2026` → `...`.`collapse_whitespace``false`Collapse runs of horizontal whitespace, trim line-end spaces, cap blank lines.`trim``false`Trim leading/trailing whitespace of the whole string.Docker
------

[](#docker)

```
docker build -t php-ai-text-sanitizer .
docker run --rm php-ai-text-sanitizer
```

Demo
----

[](#demo)

```
php src/examples/demo.php
```

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

48d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ee28fe9d54e1c97a6001a5bb443136e0627e84956b9f1e961a3ccedcf24af758?d=identicon)[iserter](/maintainers/iserter)

---

Top Contributors

[![iSerter](https://avatars.githubusercontent.com/u/1284841?v=4)](https://github.com/iSerter "iSerter (5 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/iserter-php-ai-text-sanitizer/health.svg)

```
[![Health](https://phpackages.com/badges/iserter-php-ai-text-sanitizer/health.svg)](https://phpackages.com/packages/iserter-php-ai-text-sanitizer)
```

###  Alternatives

[toplan/laravel-sms

A mobile phone number validation solution based on laravel

83580.2k2](/packages/toplan-laravel-sms)[drupal/coder

Coder is a library to review Drupal code.

3046.8M630](/packages/drupal-coder)[ph-7/eu-vat-validator

A simple and clean PHP class that validates EU VAT numbers against the central ec.europa.eu database (using the official europa API).

97510.7k1](/packages/ph-7-eu-vat-validator)[hyperf/validation

hyperf validation

122.2M213](/packages/hyperf-validation)[udokmeci/yii2-phone-validator

Modern Yii2 Phone validator wrapper on top of PhoneNumberUtil library also used by Android devices

36227.5k1](/packages/udokmeci-yii2-phone-validator)[snowcap/vat-validation

EU VAT number validation

10112.3k](/packages/snowcap-vat-validation)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
