1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
open Pcre2
let parse_args () =
let quick = ref false
and first = ref false
and ignore_case = ref false
and offset = ref 0
and pat = ref None
and substr = ref None in
let q =
( "-q",
Arg.Set quick,
"Quick replacement. Interpretes substitution as plain text." )
and f = ("-f", Arg.Set first, "Replace first occurrence in line only.")
and i = ("-i", Arg.Set ignore_case, "Ignore case.")
and ofs =
("-ofs", Arg.Int (fun n -> offset := n), "Start matching at column n.")
and usage =
"Usage: subst [-q] [-f] [-i] [-ofs offset] pattern substitution\n\n\
Reads lines from standard input and replaces occurrences of\n\
the PERL-style regular expression \"pattern\" with \"substitution\",\n\
printing the result to standard output.\n\
In default mode the contents of \"substitution\" will be interpreted\n\
similarly to its equivalent in PERL.\n"
and anon_arg arg =
match (!pat, !substr) with
| None, _ -> pat := Some arg
| _, None -> substr := Some arg
| _ -> raise (Arg.Bad "too many arguments!")
in
let args = [ q; f; i; ofs ] in
Arg.parse args anon_arg usage;
let flags = if !ignore_case then [ `CASELESS ] else [] in
let rex, sstr =
match (!pat, !substr) with
| Some rex, Some sstr -> (regexp ~flags rex, sstr)
| _ ->
prerr_endline (Sys.argv.(0) ^ ": not enough arguments!");
Arg.usage args usage;
exit 1
in
match (!quick, !first) with
| false, false -> fun s -> replace ~rex ~pos:!offset ~templ:sstr s
| true, false -> fun s -> qreplace ~rex ~pos:!offset ~templ:sstr s
| false, true -> fun s -> replace_first ~rex ~pos:!offset ~templ:sstr s
| true, true -> fun s -> qreplace_first ~rex ~pos:!offset ~templ:sstr s
let _ =
let substitute = parse_args () in
foreach_line (fun line ->
try print_endline (substitute line)
with Invalid_argument _ -> print_endline line)
|