CREATE EXTENSION IF NOT EXISTS plv8;
CREATE EXTENSION IF NOT EXISTS plperl;

CREATE OR REPLACE FUNCTION regexp_match_pg(subject text, pattern text, flags text)
RETURNS text[]
LANGUAGE plpgsql AS
$$
BEGIN
  RETURN regexp_match(subject, pattern, flags);
EXCEPTION WHEN OTHERS THEN
  RETURN ARRAY[SQLERRM];
END
$$;

CREATE OR REPLACE FUNCTION regexp_match_v8(subject text, pattern text, flags text)
RETURNS text[]
LANGUAGE plv8 AS
$$
return subject.match(new RegExp(pattern, flags));
$$;

CREATE OR REPLACE FUNCTION regexp_match_pl(subject text, pattern text, flags text DEFAULT '')
RETURNS text[]
LANGUAGE plperl AS
$$
my ($subject, $pattern, $flags) = @_;
my @m = $subject =~ m/(?$flags)$pattern/;
return \@m;
$$;

SELECT
  regexp_match_pg(E'foo!\n!bar', '(.+)', 'n'),
  (regexp_match_v8(E'foo!\n!bar', '(.+)', ''))[2:],
  regexp_match_pl(E'foo!\n!bar', '(.+)', '')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '(.+)', ''),
  (regexp_match_v8(E'foo!\n!bar', '(.+)', 's'))[2:],
  regexp_match_pl(E'foo!\n!bar', '(.+)', 's')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '([\w\W]+)', 'n'),
  (regexp_match_v8(E'foo!\n!bar', '([\w\W]+)', ''))[2:],
  regexp_match_pl(E'foo!\n!bar', '([\w\W]+)', '')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '([\w\W]+)', ''),
  (regexp_match_v8(E'foo!\n!bar', '([\w\W]+)', 's'))[2:],
  regexp_match_pl(E'foo!\n!bar', '([\w\W]+)', 's')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '([\w]+)', 'n'),
  (regexp_match_v8(E'foo!\n!bar', '([\w]+)', ''))[2:],
  regexp_match_pl(E'foo!\n!bar', '([\w]+)', '')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '([\w]+)', ''),
  (regexp_match_v8(E'foo!\n!bar', '([\w]+)', 's'))[2:],
  regexp_match_pl(E'foo!\n!bar', '([\w]+)', 's')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '([\W]+)', 'n'),
  (regexp_match_v8(E'foo!\n!bar', '([\W]+)', ''))[2:],
  regexp_match_pl(E'foo!\n!bar', '([\W]+)', '')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '([\W]+)', ''),
  (regexp_match_v8(E'foo!\n!bar', '([\W]+)', 's'))[2:],
  regexp_match_pl(E'foo!\n!bar', '([\W]+)', 's')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '(\w+)', 'n'),
  (regexp_match_v8(E'foo!\n!bar', '(\w+)', ''))[2:],
  regexp_match_pl(E'foo!\n!bar', '(\w+)', '')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '(\w+)', ''),
  (regexp_match_v8(E'foo!\n!bar', '(\w+)', 's'))[2:],
  regexp_match_pl(E'foo!\n!bar', '(\w+)', 's')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '(\W+)', 'n'),
  (regexp_match_v8(E'foo!\n!bar', '(\W+)', ''))[2:],
  regexp_match_pl(E'foo!\n!bar', '(\W+)', '')
;

SELECT
  regexp_match_pg(E'foo!\n!bar', '(\W+)', ''),
  (regexp_match_v8(E'foo!\n!bar', '(\W+)', 's'))[2:],
  regexp_match_pl(E'foo!\n!bar', '(\W+)', 's')
;
