PHPackages                             wandersonwhcr/romans - 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. [Search &amp; Filtering](/categories/search)
4. /
5. wandersonwhcr/romans

ActiveLibrary[Search &amp; Filtering](/categories/search)

wandersonwhcr/romans
====================

A Simple PHP Roman Numerals Library

v1.5.2(4y ago)44395.1k↓16.5%3[4 issues](https://github.com/wandersonwhcr/romans/issues)[1 PRs](https://github.com/wandersonwhcr/romans/pulls)8MITPHPPHP &gt;=8.0

Since Apr 7Pushed 1y ago1 watchersCompare

[ Source](https://github.com/wandersonwhcr/romans)[ Packagist](https://packagist.org/packages/wandersonwhcr/romans)[ RSS](/packages/wandersonwhcr-romans/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (6)Dependencies (7)Versions (44)Used By (8)

romans
======

[](#romans)

A Simple PHP Roman Numerals Library

[![Build Status](https://github.com/wandersonwhcr/romans/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/wandersonwhcr/romans/actions/workflows/test.yml?query=branch%3Amain)[![Updated](https://github.com/wandersonwhcr/romans/actions/workflows/updated.yml/badge.svg)](https://github.com/wandersonwhcr/romans/actions/workflows/updated.yml)[![Latest Stable Version](https://camo.githubusercontent.com/b59db253dc6ce914d972ca5bbf37d3d9bacee86416a07361c57c5646aa197e1f/68747470733a2f2f706f7365722e707567782e6f72672f77616e646572736f6e776863722f726f6d616e732f762f737461626c653f666f726d61743d666c6174)](https://packagist.org/packages/wandersonwhcr/romans)[![codecov](https://camo.githubusercontent.com/9c0f20337f4c99764e9172b7fcefe8e9944d2362035a620b672b4b8c735cbe9b/68747470733a2f2f636f6465636f762e696f2f67682f77616e646572736f6e776863722f726f6d616e732f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/wandersonwhcr/romans)[![License](https://camo.githubusercontent.com/eb746670185a78b9c34df39bbc75240a0ad3cc8f2600b5505d8fb2b772a88fb5/68747470733a2f2f706f7365722e707567782e6f72672f77616e646572736f6e776863722f726f6d616e732f6c6963656e73653f666f726d61743d666c6174)](https://packagist.org/packages/wandersonwhcr/romans)[![StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md)

Usage
-----

[](#usage)

This library includes a simple couple of filters to convert a `string` with Roman number to an `int` that represents the input as decimal and decimal `int`to a `string` with Roman number as result.

```
use Romans\Filter\RomanToInt;

$filter = new RomanToInt();
$result = $filter->filter('MCMXCIX'); // 1999
```

```
use Romans\Filter\IntToRoman;

$filter = new IntToRoman();
$result = $filter->filter(1999); // MCMXCIX
```

Installation
------------

[](#installation)

This package uses [Composer](https://packagist.org/packages/wandersonwhcr/romans) as default repository. You can install it adding the name of package in `require` section of `composer.json`, pointing to the last stable version.

```
{
  "require": {
    "wandersonwhcr/romans": "^1.0"
  }
}
```

Also, Romans uses Semantic Versioning. The following package versions support these PHP releases:

- Romans `1.0.*`: PHP `^7.0` (Augustus)
- Romans `1.1.*`: PHP `^7.0` (Tiberius)
- Romans `1.2.*`: PHP `>=7.4` (Caligula)
- Romans `1.3.*`: PHP `>=7.4` (Claudius)
- Romans `1.4.*`: PHP `>=7.4` (Nero)
- Romans `1.5.*`: PHP `>=8.0` (Galba)

Integrations
------------

[](#integrations)

This library can be used as dependency for projects, making integrations with libraries or frameworks easier. If you want to add more items in this list, please, open an issue or create a pull request, adding your project alphabetically.

- [Illuminate Romans](https://github.com/wandersonwhcr/illuminate-romans): Laravel Illuminate Romans Integration
- [Kirby Romans](https://github.com/moevbiz/k3-romans): Kirby CMS Integration
- [Laminas Romans](https://github.com/wandersonwhcr/laminas-romans): Laminas Project Romans Integration
- [Plates Romans Extension](https://github.com/wandersonwhcr/plates-romans): Plates Extension
- [Twig Roman Numerals Extension](https://github.com/EmilMassey/twig-roman-numerals): Twig Extension (Symfony, WordPress + Timber)
- [Zend Romans](https://github.com/wandersonwhcr/zend-romans): Zend Framework Romans Integration **DEPRECATED**

Advanced Usage
--------------

[](#advanced-usage)

The `Romans` package uses a Lexer-Parser approach and a Deterministic Finite Automaton (DFA) to convert Roman number to `int`, using a Grammar Token library.

```
use Romans\Grammar\Grammar;
use Romans\Lexer\Lexer;
use Romans\Parser\Parser;

$grammar = new Grammar();
$lexer   = new Lexer($grammar);
$parser  = new Parser($grammar);

$tokens = $lexer->tokenize('MCMXCIX');

/*
$tokens = [
    0 => 'M'  // Grammar::T_M
    1 => 'C', // Grammar::T_C
    2 => 'M', // Grammar::T_M
    3 => 'X', // Grammar::T_X
    4 => 'C', // Grammar::T_C
    5 => 'I', // Grammar::T_I
    6 => 'X', // Grammar::T_X
];
*/

$result = $parser->parse($tokens); // 1999
```

### Exception Handling

[](#exception-handling)

The filter `RomanToInt` uses Lexer to tokenize the input and Parser to build the `int` number. When errors are found, the Lexer or Parser throw Exceptions to notify the problem with a specific code.

```
use Romans\Filter\RomanToInt;
use Romans\Lexer\Exception as LexerException;
use Romans\Parser\Exception as ParserException;

$filter = new RomanToInt();

try {
    $filter->filter($input);
} catch (LexerException $e) {
    // Unknown Token (LexerException::UNKNOWN_TOKEN)
} catch (ParserException $e) {
    // Invalid Token Type (Not String) (ParserException::INVALID_TOKEN_TYPE)
    // Unknown Token (ParserException::UNKNOWN_TOKEN)
    // Invalid Roman (ParserException::INVALID_ROMAN)
}
```

You can use this structure to validate Roman numbers, adding a *try..catch*block to check if `$input` is valid. Also, you can validate if an `int` can be filtered to Roman using an `IntToRoman` filter.

```
use Romans\Filter\IntToRoman;
use Romans\Filter\Exception as FilterException;

$filter = new IntToRoman();

try {
    $filter->filter($input);
} catch (FilterException $e) {
    // Invalid Integer (< 0) (FilterException::INVALID_INTEGER)
}
```

### Zero

[](#zero)

The zero value is represented as `string` `"N"`, the initial of *nulla* or *nihil*, the Latin word for "nothing" (see references).

```
use Romans\Filter\RomanToInt;
use Romans\Filter\IntToRoman;

$filter = new RomanToInt();
$result = $filter->filter('N'); // 0 (Zero)

$filter = new IntToRoman();
$result = $filter->filter(0); // N
```

### Cache

[](#cache)

This package uses [PSR-6 Caching Interface](https://www.php-fig.org/psr/psr-6)to improve execution, mainly over loops (like `while` or `foreach`) using cache libraries. Any PSR-6 implementation can be used and we suggest [Symfony Cache](https://packagist.org/packages/symfony/cache) package.

```
use Romans\Filter\IntToRoman;
use Romans\Filter\RomanToInt;
use Symfony\Component\Cache\Adapter\ArrayAdapter;

$cache = new ArrayAdapter();

$filter = new RomanToInt();
$filter->setCache($cache);
$result = $filter->filter('MCMXCIX'); // 1999
$result = $filter->filter('MCMXCIX'); // 1999 (from cache)

$filter = new IntToRoman();
$filter->setCache($cache);
$result = $filter->filter(1999); // MCMXCIX
$result = $filter->filter(1999); // MCMXCIX (from cache)
```

Development
-----------

[](#development)

You can use Docker Compose to build an image and run a container to develop and test this package.

```
docker-compose build
docker-compose run --rm romans composer install
docker-compose run --rm romans composer test
```

Techniques
----------

[](#techniques)

This section describes techniques used by this package to convert Roman numbers into `int` and vice-versa.

### Lexer-Parser

[](#lexer-parser)

A Lexer-Parser approach was chosen because the validating and reading of Roman numbers are more simplified: the Lexer is responsible for reading and transform the input into tokens, validating content at char level; and the Parser is responsible for transform tokens into numbers, validating content at position level and converting to `int` through a DFA.

Wikipedia says that "lexical analysis is the process of converting a sequence of characters into a sequence of tokens", that "is a structure representing a lexeme that explicity indicates its categorization for the purpose of parsing". Even, Wikipedia says that "parsing or syntax analysis is the process of analysing symbols conforming to the rules of a formal grammar".

This structure makes easier the development of a structure responsible to read an input `string`, converting it to another structure according to specific charset and its position inside input.

### Deterministic Finite Automaton (DFA)

[](#deterministic-finite-automaton-dfa)

A DFA was developed to check if a `string` with Roman number is valid. This technique was choiced because other implementations simply convert the input without checking rules, like four chars sequentially.

The current automaton definition is declared below.

```
M  = (Q, Σ, δ, q0, F)
Q  = { a, b, c, d, e, f, g, y, z }
Σ  = { I, V, X, L, C, D, M, N }
q0 = g
F  = { z }

z -> ε
y -> $z
a -> y | Iy  | IIy | IIIy
b -> a | IVy | Va  | IXy
c -> b | Xb  | XXb | XXXb
d -> c | XLb | Lc  | XCb
e -> d | Cd  | CCd | CCCd
f -> e | CDd | De  | CMd
g -> f | Ny  | Mg

```

References
----------

[](#references)

- Rapid Tables: [How to Convert Roman Numerals to Numbers](http://www.rapidtables.com/convert/number/how-roman-numerals-to-number.htm)
- Wikipedia: [Zero in Roman Numerals](https://en.wikipedia.org/wiki/Roman_numerals#Zero)
- Wikipedia: [Lexical Analysis](https://en.wikipedia.org/wiki/Lexical_analysis)
- Wikipedia: [Parsing](https://en.wikipedia.org/wiki/Parsing)
- Wikipedia: [Deterministic Finite Automaton](https://en.wikipedia.org/wiki/Deterministic_finite_automaton)

License
-------

[](#license)

This package is opensource and available under MIT license described in [LICENSE](https://github.com/wandersonwhcr/romans/blob/main/LICENSE).

###  Health Score

48

—

FairBetter than 95% of packages

Maintenance26

Infrequent updates — may be unmaintained

Popularity46

Moderate usage in the ecosystem

Community21

Small or concentrated contributor base

Maturity81

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 99.5% 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

Every ~42 days

Recently: every ~61 days

Total

42

Last Release

1609d ago

Major Versions

v0.4.0 → v1.0.02017-04-09

PHP version history (4 changes)v1.0.0PHP ^7.0

v1.1.4PHP &gt;=7.0

v1.3.0PHP &gt;=7.4

v1.5.0PHP &gt;=8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/907c8faa9e7d6e1777b18bafcc2b94909b1b82a9fe15b462fb18b02f88a00da1?d=identicon)[wandersonwhcr](/maintainers/wandersonwhcr)

---

Top Contributors

[![wandersonwhcr](https://avatars.githubusercontent.com/u/5286703?v=4)](https://github.com/wandersonwhcr "wandersonwhcr (584 commits)")[![ianmustafa](https://avatars.githubusercontent.com/u/5209746?v=4)](https://github.com/ianmustafa "ianmustafa (1 commits)")[![moevbiz](https://avatars.githubusercontent.com/u/38008341?v=4)](https://github.com/moevbiz "moevbiz (1 commits)")[![pdenis](https://avatars.githubusercontent.com/u/1713289?v=4)](https://github.com/pdenis "pdenis (1 commits)")

---

Tags

composerconverterfilterformatphpromanroman-numberroman-numeralvalidatorvalidatorconverterformatfilterromanroman-numberroman-numeral

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/wandersonwhcr-romans/health.svg)

```
[![Health](https://phpackages.com/badges/wandersonwhcr-romans/health.svg)](https://phpackages.com/packages/wandersonwhcr-romans)
```

###  Alternatives

[clue/stream-filter

A simple and modern approach to stream filtering in PHP

1.7k261.7M7](/packages/clue-stream-filter)[aura/filter

Filters to validate and sanitize objects and arrays.

173561.0k10](/packages/aura-filter)[laminas/laminas-filter

Programmatically filter and normalize data and files

9528.0M150](/packages/laminas-laminas-filter)

PHPackages © 2026

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