String replacement in OCaml
Re version, since it was amusing to do. My version uses a slightly different technique: I build one big regexp, with two groups and replace everything in one go without any additional checking. If Re.replace provided slightly more control (per-group substitution) it would avoid the concatenation.

I used the combinators for building the regexp, instead of the symbolic version, because that's much more readable, really.

let map_to_umlauts =
  [ "ue","ü" ; "oe","ö" ; "ae","ä" ; "Ue","Ü" ; "Oe","Ö" ; "Ae","Ä" ]

let regexp =
  let open Re in compile @@
  seq [
    group @@ alt [ bow ; compl [no_case @@ set "aeiouy"] ] ;
    group @@ alt (List.map (fun (s,_) -&gt; str s) map_to_umlauts) ;
  ]

let replace s =
  let f subs =
    Re.get subs 1 ^ List.assoc (Re.get subs 2) map_to_umlauts
  in
  Re.replace ~f regexp s

let () =
  print_endline @@ replace Sys.argv.(1)


On your version, apart from the change in algorithm, I have only one comment: You really don't need a regexp to check if a char is a voyel. ;)

Also, do note all of this is playing fast and, more important, very very loose, with Unicode.