Skip to content

Commit

Permalink
Improve some regex functions
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsogarciacaro committed Nov 22, 2021
1 parent cd8913c commit 7f494c4
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 25 deletions.
25 changes: 20 additions & 5 deletions src/Fable.Transforms/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2916,8 +2916,7 @@ let regex com (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Exp
| Some (ExprType (EntFullName "System.Text.RegularExpressions.Group")) -> true
| _ -> false

match i.CompiledName with
| ".ctor" ->
let createRegex r t args =
let makeRegexConst r (pattern: string) flags =
let flags = RegexFlag.RegexGlobal::flags // .NET regex are always global
RegexConstant(pattern, flags) |> makeValue r
Expand All @@ -2935,9 +2934,12 @@ let regex com (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Exp
| _ -> None
getFlags e
match args with
| [StringConst pattern] -> makeRegexConst r pattern [] |> Some
| StringConst pattern::(RegexFlags flags)::_ -> makeRegexConst r pattern flags |> Some
| _ -> Helper.LibCall(com, "RegExp", "create", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| [StringConst pattern] -> makeRegexConst r pattern []
| StringConst pattern::(RegexFlags flags)::_ -> makeRegexConst r pattern flags
| _ -> Helper.LibCall(com, "RegExp", "create", t, args, ?loc=r)

match i.CompiledName with
| ".ctor" -> createRegex r t args |> Some
| "get_Options" -> Helper.LibCall(com, "RegExp", "options", t, [thisArg.Value], [thisArg.Value.Type], ?loc=r) |> Some
// Capture
| "get_Index" ->
Expand Down Expand Up @@ -2986,6 +2988,19 @@ let regex com (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Exp
| "get_Item" -> getExpr r t thisArg.Value args.Head |> Some
| "get_Count" -> propStr "length" thisArg.Value |> Some
| "GetEnumerator" -> getEnumerator com r t thisArg.Value |> Some
| "IsMatch" | "Match" | "Matches" as meth ->
match thisArg, args with
| Some thisArg, args ->
if args.Length > 2 then
$"Regex.{meth} doesn't support more than 2 arguments"
|> addError com ctx.InlinePath r
thisArg::args |> Some
| None, input::pattern::args ->
let reg = createRegex None Any (pattern::args)
[reg; input] |> Some
| _ -> None
|> Option.map (fun args ->
Helper.LibCall(com, "RegExp", Naming.lowerFirst meth, t, args, i.SignatureArgTypes, ?loc=r))
| meth ->
let meth = Naming.removeGetSetPrefix meth |> Naming.lowerFirst
Helper.LibCall(com, "RegExp", meth, t, args, i.SignatureArgTypes, ?thisArg=thisArg, ?loc=r) |> Some
Expand Down
31 changes: 11 additions & 20 deletions src/fable-library/RegExp.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export type MatchEvaluator = (match: any) => string;

export function create(pattern: string, options: number = 0) {
export function create(pattern: string, options = 0) {
// Supported RegexOptions
// * IgnoreCase: 0x0001
// * Multiline: 0x0002
Expand All @@ -25,35 +25,26 @@ export function unescape(str: string) {
return str.replace(/\\([\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|])/g, "$1");
}

export function isMatch(str: string | RegExp, pattern: string, options: number = 0) {
let reg: RegExp;
reg = str instanceof RegExp
? (reg = str as RegExp, str = pattern, reg.lastIndex = options, reg)
: reg = create(pattern, options);
return reg.test(str as string);
export function isMatch(reg: RegExp, input: string, startAt = 0) {
reg.lastIndex = startAt;
return reg.test(input);
}

export function match(str: string | RegExp, pattern: string, options: number = 0) {
let reg: RegExp;
reg = str instanceof RegExp
? (reg = str as RegExp, str = pattern, reg.lastIndex = options, reg)
: reg = create(pattern, options);
return reg.exec(str as string);
export function match(reg: RegExp, input: string, startAt = 0) {
reg.lastIndex = startAt;
return reg.exec(input);
}

export function matches(str: string | RegExp, pattern: string, options: number = 0) {
let reg: RegExp;
reg = str instanceof RegExp
? (reg = str as RegExp, str = pattern, reg.lastIndex = options, reg)
: reg = create(pattern, options);
export function matches(reg: RegExp, input: string, startAt = 0) {
reg.lastIndex = startAt;
if (!reg.global) {
throw new Error("Non-global RegExp"); // Prevent infinite loop
}
let m = reg.exec(str as string);
let m = reg.exec(input);
const matches: RegExpExecArray[] = [];
while (m !== null) {
matches.push(m);
m = reg.exec(str as string);
m = reg.exec(input);
}
return matches;
}
Expand Down

0 comments on commit 7f494c4

Please sign in to comment.