diff options
| author | natsuoto <[email protected]> | 2026-07-11 16:46:15 +0530 |
|---|---|---|
| committer | natsuoto <[email protected]> | 2026-07-11 16:46:15 +0530 |
| commit | 1d751146b2435fc5baf8cd903d2f88d2ac9ebd83 (patch) | |
| tree | 8c3bafe7e77ef81617a7cd8016624b607f75f46c | |
| parent | 665c9b18a7bf1025aae26fb440efff4c2b0d31d0 (diff) | |
| download | edify-1d751146b2435fc5baf8cd903d2f88d2ac9ebd83.tar.xz edify-1d751146b2435fc5baf8cd903d2f88d2ac9ebd83.zip | |
refactor(library): rewrite web/, security/, media/ validators to fluent Pattern() chain
27 files changed, 632 insertions, 62 deletions
diff --git a/edify/library/media/charset.py b/edify/library/media/charset.py index f0d83b4..eedba45 100644 --- a/edify/library/media/charset.py +++ b/edify/library/media/charset.py @@ -2,7 +2,22 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -charset = RegexBackedPattern(r"^[a-zA-Z][a-zA-Z0-9_+.\-]{1,39}$") +charset = ( + Pattern() + .start_of_input() + .letter() + .between(1, 39) + .any_of() + .range("a", "z") + .range("A", "Z") + .range("0", "9") + .char("_") + .char("+") + .char(".") + .char("-") + .end() + .end_of_input() +) """Callable :class:`Pattern` for an IANA character-set name.""" diff --git a/edify/library/media/codec.py b/edify/library/media/codec.py index 2ab3040..156493a 100644 --- a/edify/library/media/codec.py +++ b/edify/library/media/codec.py @@ -2,7 +2,21 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -codec = RegexBackedPattern(r"^[a-zA-Z][a-zA-Z0-9_.\-]{1,29}$") +codec = ( + Pattern() + .start_of_input() + .letter() + .between(1, 29) + .any_of() + .range("a", "z") + .range("A", "Z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .end() + .end_of_input() +) """Callable :class:`Pattern` for a media codec name (``h264``, ``vp9``, ``aac``, etc.).""" diff --git a/edify/library/media/encoding.py b/edify/library/media/encoding.py index 5f8f624..5a0bf17 100644 --- a/edify/library/media/encoding.py +++ b/edify/library/media/encoding.py @@ -1,8 +1,23 @@ -"""``encoding`` — text encoding name shape.""" +"""``encoding`` — text-encoding name shape.""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -encoding = RegexBackedPattern(r"^[a-zA-Z][a-zA-Z0-9_+.\-]{1,39}$") +encoding = ( + Pattern() + .start_of_input() + .letter() + .between(1, 39) + .any_of() + .range("a", "z") + .range("A", "Z") + .range("0", "9") + .char("_") + .char("+") + .char(".") + .char("-") + .end() + .end_of_input() +) """Callable :class:`Pattern` for a text-encoding name (utf-8, latin-1, etc.).""" diff --git a/edify/library/media/extension.py b/edify/library/media/extension.py index 5ecd564..2a350bd 100644 --- a/edify/library/media/extension.py +++ b/edify/library/media/extension.py @@ -1,8 +1,15 @@ -"""``extension`` — file extension shape (``.ext``).""" +"""``extension`` — file extension shape.""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -extension = RegexBackedPattern(r"^\.[a-zA-Z0-9]{1,10}$") +extension = ( + Pattern() + .start_of_input() + .char(".") + .between(1, 10) + .alphanumeric() + .end_of_input() +) """Callable :class:`Pattern` for a file extension: dot + 1-10 alphanumeric.""" diff --git a/edify/library/media/favicon.py b/edify/library/media/favicon.py index f032398..aca9523 100644 --- a/edify/library/media/favicon.py +++ b/edify/library/media/favicon.py @@ -1,8 +1,43 @@ -"""``favicon`` — favicon filename/URL shape.""" +"""``favicon`` — favicon file name or URL path shape.""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -favicon = RegexBackedPattern(r"^(?:[^\x00-\x1f/\\]+/)*favicon\.(?:ico|png|svg|gif)$") + +def _not_ctrl_or_seps() -> Pattern: + return ( + Pattern() + .assert_not_ahead() + .any_of() + .range("\x00", "\x1f") + .char("/") + .char("\\") + .end() + .end() + .any_char() + ) + + +favicon = ( + Pattern() + .start_of_input() + .zero_or_more() + .group() + .one_or_more() + .subexpression(_not_ctrl_or_seps()) + .char("/") + .end() + .string("favicon") + .char(".") + .group() + .any_of() + .string("ico") + .string("png") + .string("svg") + .string("gif") + .end() + .end() + .end_of_input() +) """Callable :class:`Pattern` for a favicon file name or URL path.""" diff --git a/edify/library/media/filename.py b/edify/library/media/filename.py index 3fdff61..0c1ef2c 100644 --- a/edify/library/media/filename.py +++ b/edify/library/media/filename.py @@ -1,8 +1,39 @@ -"""``filename`` — file name shape (basename with extension).""" +"""``filename`` — valid filename with extension shape.""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -filename = RegexBackedPattern(r"^[^\x00-\x1f/\\:*?\"<>|]+\.[a-zA-Z0-9]{1,10}$") + +def _not_ctrl_or_reserved() -> Pattern: + return ( + Pattern() + .assert_not_ahead() + .any_of() + .range("\x00", "\x1f") + .char("/") + .char("\\") + .char(":") + .char("*") + .char("?") + .char('"') + .char("<") + .char(">") + .char("|") + .end() + .end() + .any_char() + ) + + +filename = ( + Pattern() + .start_of_input() + .one_or_more() + .subexpression(_not_ctrl_or_reserved()) + .char(".") + .between(1, 10) + .alphanumeric() + .end_of_input() +) """Callable :class:`Pattern` for a valid file name with extension.""" diff --git a/edify/library/media/glob.py b/edify/library/media/glob.py index 2bbfae9..4a4cfde 100644 --- a/edify/library/media/glob.py +++ b/edify/library/media/glob.py @@ -1,8 +1,30 @@ -"""``glob`` — Unix glob-pattern shape.""" +"""``glob`` — Unix glob shape (must contain a wildcard).""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -glob = RegexBackedPattern(r"^[^\x00-\x1f]*[*?[\]][^\x00-\x1f]*$") + +def _not_ctrl() -> Pattern: + return ( + Pattern() + .assert_not_ahead() + .any_of() + .range("\x00", "\x1f") + .end() + .end() + .any_char() + ) + + +glob = ( + Pattern() + .start_of_input() + .zero_or_more() + .subexpression(_not_ctrl()) + .any_of_chars("*?[]") + .zero_or_more() + .subexpression(_not_ctrl()) + .end_of_input() +) """Callable :class:`Pattern` for a Unix glob (must contain at least one wildcard).""" diff --git a/edify/library/media/locale.py b/edify/library/media/locale.py index 8f5e401..eecf5c4 100644 --- a/edify/library/media/locale.py +++ b/edify/library/media/locale.py @@ -1,8 +1,37 @@ -"""``locale`` — POSIX/BCP-47 locale-tag shape.""" +"""``locale`` — POSIX/BCP-47 locale tag shape.""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -locale = RegexBackedPattern(r"^[a-z]{2,3}(?:[_-][A-Z]{2})?(?:\.[a-zA-Z0-9-]+)?(?:@[a-zA-Z0-9]+)?$") +locale = ( + Pattern() + .start_of_input() + .between(2, 3) + .lowercase() + .optional() + .group() + .any_of_chars("_-") + .exactly(2) + .uppercase() + .end() + .optional() + .group() + .char(".") + .one_or_more() + .any_of() + .range("a", "z") + .range("A", "Z") + .range("0", "9") + .char("-") + .end() + .end() + .optional() + .group() + .char("@") + .one_or_more() + .alphanumeric() + .end() + .end_of_input() +) """Callable :class:`Pattern` for a POSIX/BCP-47 locale tag (``en``, ``en_US``, ``en-US.UTF-8``).""" diff --git a/edify/library/media/mimetype.py b/edify/library/media/mimetype.py index 65c54e6..5130b88 100644 --- a/edify/library/media/mimetype.py +++ b/edify/library/media/mimetype.py @@ -1,8 +1,38 @@ -"""``mimetype`` — RFC 6838 MIME type shape.""" +"""``mimetype`` — ``type/subtype`` MIME shape.""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -mimetype = RegexBackedPattern(r"^[a-zA-Z][a-zA-Z0-9!#$&\-^_.+]*/[a-zA-Z][a-zA-Z0-9!#$&\-^_.+]*$") + +def _mime_body() -> Pattern: + return ( + Pattern() + .letter() + .zero_or_more() + .any_of() + .range("a", "z") + .range("A", "Z") + .range("0", "9") + .char("!") + .char("#") + .char("$") + .char("&") + .char("-") + .char("^") + .char("_") + .char(".") + .char("+") + .end() + ) + + +mimetype = ( + Pattern() + .start_of_input() + .subexpression(_mime_body()) + .char("/") + .subexpression(_mime_body()) + .end_of_input() +) """Callable :class:`Pattern` for the ``type/subtype`` MIME shape.""" diff --git a/edify/library/media/shebang.py b/edify/library/media/shebang.py index 83f6ce9..67e5a71 100644 --- a/edify/library/media/shebang.py +++ b/edify/library/media/shebang.py @@ -1,8 +1,42 @@ -"""``shebang`` — script shebang line shape.""" +"""``shebang`` — shebang line shape.""" from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -shebang = RegexBackedPattern(r"^#!/(?:usr/)?(?:bin|sbin|local)/(?:env\s+)?[a-zA-Z0-9._+/-]+$") +shebang = ( + Pattern() + .start_of_input() + .string("#!/") + .optional() + .group() + .string("usr/") + .end() + .group() + .any_of() + .string("bin") + .string("sbin") + .string("local") + .end() + .end() + .char("/") + .optional() + .group() + .string("env") + .one_or_more() + .whitespace_char() + .end() + .one_or_more() + .any_of() + .range("a", "z") + .range("A", "Z") + .range("0", "9") + .char(".") + .char("_") + .char("+") + .char("/") + .char("-") + .end() + .end_of_input() +) """Callable :class:`Pattern` for a shebang line at the top of a script.""" diff --git a/edify/library/security/age.py b/edify/library/security/age.py index 39ec2ea..900299c 100644 --- a/edify/library/security/age.py +++ b/edify/library/security/age.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -age = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +age = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for age cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/certificate.py b/edify/library/security/certificate.py index 171cf40..237b99d 100644 --- a/edify/library/security/certificate.py +++ b/edify/library/security/certificate.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -certificate = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +certificate = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for certificate cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/csr.py b/edify/library/security/csr.py index 6bacb42..14bd5eb 100644 --- a/edify/library/security/csr.py +++ b/edify/library/security/csr.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -csr = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +csr = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for csr cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/der.py b/edify/library/security/der.py index 3cd2e3e..b9d5a14 100644 --- a/edify/library/security/der.py +++ b/edify/library/security/der.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -der = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +der = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for der cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/keyring.py b/edify/library/security/keyring.py index 2442189..d91f57a 100644 --- a/edify/library/security/keyring.py +++ b/edify/library/security/keyring.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -keyring = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +keyring = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for keyring cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/pem.py b/edify/library/security/pem.py index fd63352..1bbdc9b 100644 --- a/edify/library/security/pem.py +++ b/edify/library/security/pem.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -pem = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +pem = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for pem cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/pgp.py b/edify/library/security/pgp.py index bc6dadd..7499d95 100644 --- a/edify/library/security/pgp.py +++ b/edify/library/security/pgp.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -pgp = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +pgp = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for pgp cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/ssh.py b/edify/library/security/ssh.py index be3c415..782df53 100644 --- a/edify/library/security/ssh.py +++ b/edify/library/security/ssh.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -ssh = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +ssh = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for ssh cryptographic-artifact identifier or payload.""" diff --git a/edify/library/security/x509.py b/edify/library/security/x509.py index e7aac16..cb47d61 100644 --- a/edify/library/security/x509.py +++ b/edify/library/security/x509.py @@ -2,7 +2,25 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -x509 = RegexBackedPattern(r"^[A-Za-z0-9+/=_\-.:\s]{16,4096}$") +x509 = ( + Pattern() + .start_of_input() + .between(16, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("+") + .char("/") + .char("=") + .char("_") + .char("-") + .char(".") + .char(":") + .whitespace_char() + .end() + .end_of_input() +) """Callable :class:`Pattern` for x509 cryptographic-artifact identifier or payload.""" diff --git a/edify/library/web/apache.py b/edify/library/web/apache.py index 3521fc4..6e82cf3 100644 --- a/edify/library/web/apache.py +++ b/edify/library/web/apache.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -apache = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +apache = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for apache web-artifact identifier or content marker.""" diff --git a/edify/library/web/captcha.py b/edify/library/web/captcha.py index 92e6300..189a349 100644 --- a/edify/library/web/captcha.py +++ b/edify/library/web/captcha.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -captcha = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +captcha = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for captcha web-artifact identifier or content marker.""" diff --git a/edify/library/web/htaccess.py b/edify/library/web/htaccess.py index 7630236..ddb3c8e 100644 --- a/edify/library/web/htaccess.py +++ b/edify/library/web/htaccess.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -htaccess = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +htaccess = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for htaccess web-artifact identifier or content marker.""" diff --git a/edify/library/web/humans.py b/edify/library/web/humans.py index 5cb305f..ae39356 100644 --- a/edify/library/web/humans.py +++ b/edify/library/web/humans.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -humans = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +humans = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for humans web-artifact identifier or content marker.""" diff --git a/edify/library/web/manifest.py b/edify/library/web/manifest.py index f48be61..fa78af8 100644 --- a/edify/library/web/manifest.py +++ b/edify/library/web/manifest.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -manifest = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +manifest = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for manifest web-artifact identifier or content marker.""" diff --git a/edify/library/web/nginx.py b/edify/library/web/nginx.py index d22420d..80e91aa 100644 --- a/edify/library/web/nginx.py +++ b/edify/library/web/nginx.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -nginx = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +nginx = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for nginx web-artifact identifier or content marker.""" diff --git a/edify/library/web/robots.py b/edify/library/web/robots.py index 322b05e..0d8a818 100644 --- a/edify/library/web/robots.py +++ b/edify/library/web/robots.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -robots = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +robots = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for robots web-artifact identifier or content marker.""" diff --git a/edify/library/web/sitemap.py b/edify/library/web/sitemap.py index cbc5335..54b1058 100644 --- a/edify/library/web/sitemap.py +++ b/edify/library/web/sitemap.py @@ -2,7 +2,29 @@ from __future__ import annotations -from edify.library._support.regex import RegexBackedPattern +from edify import Pattern -sitemap = RegexBackedPattern(r"^[A-Za-z0-9_.\-/+=?&#:%~]{2,4096}$") +sitemap = ( + Pattern() + .start_of_input() + .between(2, 4096) + .any_of() + .range("A", "Z") + .range("a", "z") + .range("0", "9") + .char("_") + .char(".") + .char("-") + .char("/") + .char("+") + .char("=") + .char("?") + .char("&") + .char("#") + .char(":") + .char("%") + .char("~") + .end() + .end_of_input() +) """Callable :class:`Pattern` for sitemap web-artifact identifier or content marker.""" |
