diff --git a/README.md b/README.md
index d6501e8e..3937b2df 100644
--- a/README.md
+++ b/README.md
@@ -11,11 +11,11 @@
-[![Static Badge](https://img.shields.io/badge/Rules-379-green?label=Total%20number%20of%20rules&labelColor=darkgreen&color=gray)](schema-examples/full.yml)
-[![Static Badge](https://img.shields.io/badge/Rules-165-green?label=Cell%20rules&labelColor=blue&color=gray)](src/Rules/Cell)
+[![Static Badge](https://img.shields.io/badge/Rules-380-green?label=Total%20number%20of%20rules&labelColor=darkgreen&color=gray)](schema-examples/full.yml)
+[![Static Badge](https://img.shields.io/badge/Rules-166-green?label=Cell%20rules&labelColor=blue&color=gray)](src/Rules/Cell)
[![Static Badge](https://img.shields.io/badge/Rules-206-green?label=Aggregate%20rules&labelColor=blue&color=gray)](src/Rules/Aggregate)
[![Static Badge](https://img.shields.io/badge/Rules-8-green?label=Extra%20checks&labelColor=blue&color=gray)](#extra-checks)
-[![Static Badge](https://img.shields.io/badge/Rules-29/54/9-green?label=Plan%20to%20add&labelColor=gray&color=gray)](tests/schemas/todo.yml)
+[![Static Badge](https://img.shields.io/badge/Rules-28/54/9-green?label=Plan%20to%20add&labelColor=gray&color=gray)](tests/schemas/todo.yml)
A console utility designed for validating CSV files against a strictly defined schema and validation rules outlined
@@ -432,6 +432,7 @@ columns:
# Specific formats
is_bool: true # Allow only boolean values "true" and "false", case-insensitive.
+ is_hex: true # Both: with or without "0x" prefix. Example: "0x1A" or "1A"
is_uuid: true # Validates whether the input is a valid UUID. It also supports validation of specific versions 1, 3, 4 and 5.
is_slug: true # Only slug format. Example: "my-slug-123". It can contain letters, numbers, and dashes.
is_currency_code: true # Validates an ISO 4217 currency code like GBP or EUR. Case-sensitive. See: https://en.wikipedia.org/wiki/ISO_4217.
diff --git a/schema-examples/full.json b/schema-examples/full.json
index ba55b349..bcd7ef5b 100644
--- a/schema-examples/full.json
+++ b/schema-examples/full.json
@@ -104,6 +104,7 @@
"date_age_max" : 100,
"is_bool" : true,
+ "is_hex" : true,
"is_uuid" : true,
"is_slug" : true,
"is_currency_code" : true,
diff --git a/schema-examples/full.php b/schema-examples/full.php
index c69740d2..d0b44e23 100644
--- a/schema-examples/full.php
+++ b/schema-examples/full.php
@@ -125,6 +125,7 @@
'date_age_max' => 100,
'is_bool' => true,
+ 'is_hex' => true,
'is_uuid' => true,
'is_slug' => true,
'is_currency_code' => true,
diff --git a/schema-examples/full.yml b/schema-examples/full.yml
index 8b7b59ef..4bbd7c1f 100644
--- a/schema-examples/full.yml
+++ b/schema-examples/full.yml
@@ -171,6 +171,7 @@ columns:
# Specific formats
is_bool: true # Allow only boolean values "true" and "false", case-insensitive.
+ is_hex: true # Both: with or without "0x" prefix. Example: "0x1A" or "1A"
is_uuid: true # Validates whether the input is a valid UUID. It also supports validation of specific versions 1, 3, 4 and 5.
is_slug: true # Only slug format. Example: "my-slug-123". It can contain letters, numbers, and dashes.
is_currency_code: true # Validates an ISO 4217 currency code like GBP or EUR. Case-sensitive. See: https://en.wikipedia.org/wiki/ISO_4217.
diff --git a/schema-examples/full_clean.yml b/schema-examples/full_clean.yml
index 90b00b7f..d9309457 100644
--- a/schema-examples/full_clean.yml
+++ b/schema-examples/full_clean.yml
@@ -132,6 +132,7 @@ columns:
date_age_max: 100
is_bool: true
+ is_hex: true
is_uuid: true
is_slug: true
is_currency_code: true
diff --git a/src/Rules/Cell/IsHex.php b/src/Rules/Cell/IsHex.php
new file mode 100644
index 00000000..240120bc
--- /dev/null
+++ b/src/Rules/Cell/IsHex.php
@@ -0,0 +1,45 @@
+ [
+ 'true',
+ 'Both: with or without "0x" prefix. Example: "0x1A" or "1A"',
+ ],
+ ],
+ ];
+ }
+
+ public function validateRule(string $cellValue): ?string
+ {
+ if (
+ \preg_match('/^[0-9a-fA-F]+$/i', $cellValue) === 0
+ && \preg_match('/^0x[0-9a-fA-F]+$/i', $cellValue) === 0
+ ) {
+ return "Value \"{$cellValue}\" is not a valid hexadecimal number. Example: \"0x1A\" or \"1A\"";
+ }
+
+ return null;
+ }
+}
diff --git a/tests/Rules/Cell/IsHexTest.php b/tests/Rules/Cell/IsHexTest.php
new file mode 100644
index 00000000..1e10ba1c
--- /dev/null
+++ b/tests/Rules/Cell/IsHexTest.php
@@ -0,0 +1,65 @@
+create(true);
+ isSame(null, $rule->validate(''));
+ isSame('', $rule->test('0'));
+ isSame('', $rule->test('1'));
+ isSame('', $rule->test('11'));
+ isSame('', $rule->test('1F'));
+ isSame('', $rule->test('ff'));
+ isSame('', $rule->test('fa'));
+
+ isSame('', $rule->test('0x1'));
+ isSame('', $rule->test('0x0'));
+ isSame('', $rule->test('0x11'));
+ isSame('', $rule->test('0x1F'));
+ isSame('', $rule->test('0xff'));
+ isSame('', $rule->test('0xfa'));
+
+ $rule = $this->create(false);
+ isSame(null, $rule->validate('1'));
+ }
+
+ public function testNegative(): void
+ {
+ $rule = $this->create(true);
+ isSame(
+ 'Value "qwerty" is not a valid hexadecimal number. Example: "0x1A" or "1A"',
+ $rule->test('qwerty'),
+ );
+
+ $rule = $this->create(true);
+ isSame(
+ '"is_hex" at line 1, column "prop". ' .
+ 'Value "qwerty" is not a valid hexadecimal number. Example: "0x1A" or "1A".',
+ (string)$rule->validate('qwerty'),
+ );
+ }
+}
diff --git a/tests/schemas/todo.yml b/tests/schemas/todo.yml
index 3854c7b3..d16a2505 100644
--- a/tests/schemas/todo.yml
+++ b/tests/schemas/todo.yml
@@ -75,7 +75,6 @@ columns:
is_card_number: true
# Strings
- is_hex: true
is_binary: true
is_charset: true
is_hex_rgb_color: true