-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(String): RegExp S.Replace
, S.Match
and S.MatchAll
#94
base: main
Are you sure you want to change the base?
feat(String): RegExp S.Replace
, S.Match
and S.MatchAll
#94
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this amazing PR @didavid61202!! 🎉
Here are a few thought:
It seems like regex parsing and evaluation is a little bit slow and it would be great if people didn’t have to pay this performance cost if they do not use the feature. I was thinking we could make regex syntax opt-in by introducing a Strings.RegEx
(maybe RegExp
, or Regex
?) constructor that you could pass to string functions:
Call<
Strings.Replace<
Strings.Regex<"/([A-Z]|!)/g">,
"_$1_",
"OaaObbOcc!"
>
>;
What do you think?
I’d love it if Regex was also supported on Strings.Split
!
Bugs
I discovered a small bug when using 2 subsequent [a-z]
ranges in a |
"or" expression.
// ✅ works
type res1 = Call<Strings.Replace<"/([A-Z]|!)/g", "_$1_", "OaaObbOcc!">>;
type test1 = Expect<Equal<res1, "_O_aa_O_bb_O_cc_!_">>;
// ❌ fails
type res2 = Call<Strings.Replace<"/([a-z][A-Z]|!)/g", "_$1_", "OaaObbOcc!">>;
type test2 = Expect<Equal<res2, "Oa_aO_b_bO_cc_!_">>;
// ✅ works
type res3 = Call<Strings.Replace<"/([a-z][A-Z])/g", "_$1_", "OaaObbOcc!">>;
type test3 = Expect<Equal<res3, "Oa_aO_b_bO_cc!">>;
Hi @gvergnaud , thanks for the suggestion and reporting the bug! // ✅ working now
type res2 = Call<Strings.Replace<"/([a-z][A-Z]|!)/g", "_$1_", "OaaObbOcc!">>;
type test2 = Expect<Equal<res2, "Oa_aO_b_bO_cc_!_">>; for making the regex syntax opt-in, with Call<
Strings.Replace<
Strings.Regex<"/([A-Z]|!)/g">,
"_$1_",
"OaaObbOcc!"
>
>; I think this might only separate and make the export interface ReplaceReducer<To extends string> extends Fn {
return: this["args"] extends [
infer Str extends string,
infer From extends string,
...any
]
? Str extends Str
? From extends `/${infer RegExp}/`
? ResovleRegExpReplaceOrError<Str, RegExp, To, never>
: From extends `/${infer RegExp}/${SupportedRegExpReplaceFlags}`
? ResovleRegExpReplaceOrError<
Str,
RegExp,
To,
Split<
From extends `/${RegExp}/${infer Flags extends SupportedRegExpReplaceFlags}`
? Flags
: never,
""
>[number]
>
: Replace<Str, From, To>
: never
: never;
} but I'm curious if this way is already making RegExp Or if we want to fully separate the types, maybe we can achieve by introducing What do you think? which way do you prefer? I'll be working on adding the support for |
From my point of view the type Regex<Regexpr extends string, Modifiers extends SupportedRegExpReplaceFlags = ""> = {
type: RegexpSymbol;
regex: Regexpr;
modifiers: Modifiers
>
export interface ReplaceReducer<To extends string> extends Fn {
return: this["args"] extends [
infer Str extends string,
infer From extends string | Regex<string>,
...any
]
? From extends Regex<infer RegExp, infer Flags>
? ResovleRegExpReplaceOrError<Str, RegExp, To, Flags>
: Replace<Str, From, To>
: never;
} |
@ecyrbe good point! |
Updates
type-level-regexp/regexp
to prevent global declaration side effects from the package.Strings.RegExp
to create a RegExp object with pattern, flags and parsed matches to use with other RegExp related hotscript fn, and returnsRegExpSyntaxError
error type with detailed error message if the provided RegExp pattern contains some syntax error (currently only show few types of error, WIP)Strings.Replace
to also accept RegExp pattern (/<pattern>/
) asfrom
arg to replace substring matched by the given pattern. Replace value also support special replacemnet patterns.Strings.Match
to match a string against a RegExp (supporti
andg
flags), returns a matched object with match array andindex
andgroups
properties.Strings.MatchAll
to match a string against a RegExp, return an array of match objects, each with a match array andindex
andgroups
properties.Note
I have kept the implementation of RegExp matching and replacing generic types in a separate package called type-level-regexp. This allows for faster iteration as it is still in the early stages, and more features and performance improvements are coming along the way.
Usage
Related issues
Resolve #33
Tasks