Regular Expressions in Standard ML
(* Standard ML offers support for regular expressions through libraries.
Here are some examples of common regexp-related tasks in Standard ML. *)
(* We'll use the SML/NJ library for regular expressions *)
structure Regexp = RegExpFn(structure P = AwkSyntax structure E = DfaEngine)
fun main () =
let
(* This tests whether a pattern matches a string *)
val match = Regexp.match (Regexp.fromString "p[a-z]+ch") "peach"
val _ = print (Bool.toString match ^ "\n")
(* For other regexp tasks, we'll compile the pattern *)
val r = Regexp.fromString "p([a-z]+)ch"
(* Here's a match test like we saw earlier *)
val _ = print (Bool.toString (Regexp.match r "peach") ^ "\n")
(* This finds the match for the regexp *)
val findString = case Regexp.find r (Substring.full "peach punch") of
SOME (_, match) => Substring.string match
| NONE => ""
val _ = print (findString ^ "\n")
(* This returns the start and end indexes for the match *)
val findStringIndex = case Regexp.find r (Substring.full "peach punch") of
SOME (start, match) =>
"idx: [" ^ Int.toString start ^ " " ^
Int.toString (start + Substring.size match) ^ "]"
| NONE => "idx: []"
val _ = print (findStringIndex ^ "\n")
(* The 'extract' function includes information about both the whole-pattern matches
and the submatches within those matches *)
val submatch = case Regexp.extract r (Substring.full "peach punch") of
SOME [whole, sub] => "[" ^ whole ^ " " ^ sub ^ "]"
| _ => "[]"
val _ = print (submatch ^ "\n")
(* Finding all matches for a regexp *)
fun findAll text =
let
fun loop start acc =
case Regexp.find r (Substring.extract (text, start, NONE)) of
SOME (pos, match) =>
loop (start + pos + Substring.size match)
(Substring.string match :: acc)
| NONE => List.rev acc
in
loop 0 []
end
val allMatches = findAll "peach punch pinch"
val _ = print (String.concatWith " " allMatches ^ "\n")
(* Replacing subsets of strings *)
val replaced = Regexp.substitute r (fn _ => "<fruit>") "a peach"
val _ = print (replaced ^ "\n")
(* Transforming matched text with a function *)
val transformed = Regexp.substitute r (fn s => String.map Char.toUpper s) "a peach"
val _ = print (transformed ^ "\n")
in
()
end
val _ = main()
This Standard ML code demonstrates similar functionality to the Go example, using the SML/NJ regular expression library. Here are some key points:
We use the
RegExpFn
functor to create aRegexp
structure with Awk-like syntax and DFA engine.Pattern matching is done using
Regexp.match
andRegexp.find
functions.Submatches are extracted using the
Regexp.extract
function.To find all matches, we implement a recursive
findAll
function.String replacement is done using the
Regexp.substitute
function.Standard ML doesn’t have built-in regular expression support, so we rely on the SML/NJ library.
Some operations, like finding string indexes, require manual calculation based on substring positions.
Error handling is mostly done through pattern matching on
SOME
andNONE
values.
Note that the exact output might differ slightly from the Go version due to differences in how Standard ML handles regular expressions and string operations. Also, some advanced features might not be directly available or might require more complex implementations in Standard ML.