26#if defined (HAVE_CONFIG_H)
63 std::size_t
len = s.length ();
69 if (s[j] ==
'\\' && j+1 <
len)
86 retval.insert (i,
"(?<=\\W|^)");
91 retval.insert (i,
"(?=\\W|$)");
97 bool bad_esc_seq = (j+1 >=
len);
100 if (! bad_esc_seq && s[++j] ==
'{')
110 int digit = s[k] -
'0';
111 if (digit < 0 || digit > 7)
116 if (bad_esc_seq || (brace && s[k++] !=
'}'))
119 warning (R
"(malformed octal escape sequence '\o' -- converting to '\0')");
153 std::size_t
len = s.length ();
159 if (s[j] ==
'\\' && j+1 <
len)
201 int tmpi = s[j] -
'0';
204 int digit = s[k] -
'0';
205 if (digit < 0 || digit > 7)
217 bool bad_esc_seq = (j+1 >=
len);
220 if (! bad_esc_seq && s[++j] ==
'{')
230 int digit = s[k] -
'0';
231 if (digit < 0 || digit > 7)
236 if (bad_esc_seq || (brace && s[k++] !=
'}'))
238 warning (R
"(malformed octal escape sequence '\o' -- converting to '\0')");
248 bool bad_esc_seq = (j+1 >=
len);
251 if (! bad_esc_seq && s[++j] ==
'{')
261 if (! isxdigit (s[k]))
267 tmpi += digit -
'a' + 10;
268 else if (digit >=
'A')
269 tmpi += digit -
'A' + 10;
273 if (bad_esc_seq || (brace && s[k++] !=
'}'))
275 warning (R
"(malformed hex escape sequence '\x' -- converting to '\0')");
288 retval[i] =
'\\'; retval[++i] =
'$';
292 retval[i] =
'\\'; retval[++i] =
'\\';
316 const std::string& who,
int skip,
bool& extra_args)
320 for (
int i = skip; i < args.
length (); i++)
324 str = args(i).xstring_value (
"%s: optional arguments must be strings", who.c_str ());
328 if (str.find (
"once", 0) == 0)
330 else if (str.find (
"matchcase", 0) == 0)
331 options.case_insensitive (
false);
332 else if (str.find (
"ignorecase", 0) == 0)
333 options.case_insensitive (
true);
334 else if (str.find (
"dotall", 0) == 0)
335 options.dotexceptnewline (
false);
336 else if (str.find (
"stringanchors", 0) == 0)
337 options.lineanchors (
false);
338 else if (str.find (
"literalspacing", 0) == 0)
339 options.freespacing (
false);
340 else if (str.find (
"noemptymatch", 0) == 0)
341 options.emptymatch (
false);
342 else if (str.find (
"dotexceptnewline", 0) == 0)
343 options.dotexceptnewline (
true);
344 else if (str.find (
"lineanchors", 0) == 0)
345 options.lineanchors (
true);
346 else if (str.find (
"freespacing", 0) == 0)
347 options.freespacing (
true);
348 else if (str.find (
"emptymatch", 0) == 0)
349 options.emptymatch (
true);
350 else if (str.find (
"start", 0) == 0
351 || str.find (
"end", 0) == 0
352 || str.find (
"tokenextents", 0) == 0
353 || str.find (
"match", 0) == 0
354 || str.find (
"tokens", 0) == 0
355 || str.find (
"names", 0) == 0
356 || str.find (
"split", 0) == 0)
359 error (
"%s: unrecognized option", who.c_str ());
365 const std::string& who,
bool case_insensitive =
false)
369 int nargin = args.
length ();
372 const std::string buffer = args(0).string_value ();
374 std::string pattern = args(1).string_value ();
379 regexp::opts options;
380 options.case_insensitive (case_insensitive);
381 bool extra_options =
false;
384 const regexp::match_data rx_lst
385 = regexp::match (pattern, buffer, options, who);
389 std::size_t sz = rx_lst.size ();
399 for (
int j = 0; j < named_pats.
numel (); j++)
404 for (
const auto& match_data : rx_lst)
408 ctmp(i++) = named_tokens(j);
411 nmap.
assign (named_pats(j), ctmp);
418 auto p = rx_lst.
begin ();
420 retval(4) = (sz ? p->tokens () :
Cell ());
421 retval(3) = (sz ? p->match_string () :
"");
422 retval(2) = (sz ? p->token_extents () :
Matrix ());
426 double start = p->start ();
427 double end = p->end ();
430 split(0) = buffer.substr (0, start-1);
431 split(1) = buffer.substr (end);
452 std::size_t sp_start = 0;
455 for (
const auto& match_data : rx_lst)
457 double s = match_data.start ();
458 double e = match_data.end ();
462 match_string(i) = match_data.match_string ();
463 token_extents(i) = match_data.token_extents ();
466 split(i) = buffer.substr (sp_start, s-sp_start-1);
471 split(i) = buffer.substr (sp_start);
475 retval(3) = match_string;
476 retval(2) = token_extents;
487 new_retval.
resize (nargout);
491 for (
int j = 2; j < nargin; j++)
494 std::string str = args(j).string_value ();
497 if (str.find (
"once", 0) == 0
498 || str.find (
"stringanchors", 0) == 0
499 || str.find (
"lineanchors", 0) == 0
500 || str.find (
"matchcase", 0) == 0
501 || str.find (
"ignorecase", 0) == 0
502 || str.find (
"dotall", 0) == 0
503 || str.find (
"dotexceptnewline", 0) == 0
504 || str.find (
"literalspacing", 0) == 0
505 || str.find (
"freespacing", 0) == 0
506 || str.find (
"noemptymatch", 0) == 0
507 || str.find (
"emptymatch", 0) == 0)
509 else if (str.find (
"start", 0) == 0)
511 else if (str.find (
"end", 0) == 0)
513 else if (str.find (
"tokenextents", 0) == 0)
515 else if (str.find (
"match", 0) == 0)
517 else if (str.find (
"tokens", 0) == 0)
519 else if (str.find (
"names", 0) == 0)
521 else if (str.find (
"split", 0) == 0)
524 new_retval(n++) = retval(k);
534 for (
int j = 0; j < 7; j++)
537 new_retval(n++) = retval(j);
549 const std::string& who,
bool case_insensitive =
false)
553 if (args(0).iscell ())
558 if (args(1).iscell ())
562 if (cellpat.
numel () == 1)
564 for (
int j = 0; j < nargout; j++)
565 newretval[j].resize (cellstr.
dims ());
567 new_args(1) = cellpat(0);
571 new_args(0) = cellstr(i);
575 for (
int j = 0; j < nargout; j++)
576 newretval[j](i) = tmp(j);
579 else if (cellstr.
numel () == 1)
581 for (
int j = 0; j < nargout; j++)
582 newretval[j].resize (cellpat.
dims ());
584 new_args(0) = cellstr(0);
588 new_args(1) = cellpat(i);
592 for (
int j = 0; j < nargout; j++)
593 newretval[j](i) = tmp(j);
596 else if (cellstr.
numel () == cellpat.
numel ())
598 if (cellstr.
dims () != cellpat.
dims ())
599 error (
"%s: inconsistent cell array dimensions", who.c_str ());
601 for (
int j = 0; j < nargout; j++)
602 newretval[j].resize (cellstr.
dims ());
606 new_args(0) = cellstr(i);
607 new_args(1) = cellpat(i);
612 for (
int j = 0; j < nargout; j++)
613 newretval[j](i) = tmp(j);
617 error (
"regexp: cell array arguments must be scalar or equal size");
621 for (
int j = 0; j < nargout; j++)
622 newretval[j].resize (cellstr.
dims ());
626 new_args(0) = cellstr(i);
630 for (
int j = 0; j < nargout; j++)
631 newretval[j](i) = tmp(j);
635 for (
int j = 0; j < nargout; j++)
638 else if (args(1).iscell ())
644 for (
int j = 0; j < nargout; j++)
645 newretval[j].resize (cellpat.
dims ());
649 new_args(1) = cellpat(i);
653 for (
int j = 0; j < nargout; j++)
654 newretval[j](i) = tmp(j);
657 for (
int j = 0; j < nargout; j++)
661 retval =
octregexp (args, nargout, who, case_insensitive);
667DEFUN (regexp, args, nargout,
888 if (args.length () < 2)
893 if (args(0).iscell () || args(1).iscell ())
894 retval = (
octcellregexp (args, (nargout > 0 ? nargout : 1),
"regexp"));
896 retval =
octregexp (args, nargout,
"regexp");
1206DEFUN (regexpi, args, nargout,
1220 if (args.length () < 2)
1223 if (args(0).iscell () || args(1).iscell ())
1224 return octcellregexp (args, (nargout > 0 ? nargout : 1),
"regexpi",
true);
1226 return octregexp (args, nargout,
"regexpi",
true);
1366 int nargin = args.
length ();
1369 const std::string buffer = args(0).string_value ();
1371 std::string pattern = args(1).string_value ();
1376 std::string replacement = args(2).string_value ();
1379 if (args(2).is_sq_string ())
1387 for (
int i = 3; i < nargin; i++)
1389 const std::string opt = args(i).string_value ();
1390 if (opt !=
"tokenize" && opt !=
"start" && opt !=
"end"
1391 && opt !=
"tokenextents" && opt !=
"match" && opt !=
"tokens"
1392 && opt !=
"names" && opt !=
"split" && opt !=
"warnings")
1394 regexpargs(
len++) = args(i);
1399 regexp::opts options;
1400 bool extra_args =
false;
1403 return regexp::replace (pattern, buffer, replacement, options, who);
1406DEFUN (regexprep, args, ,
1448 if (args.length () < 3)
1453 if (args(0).iscell () || args(1).iscell () || args(2).iscell ())
1459 if (args(0).iscell ())
1460 str = args(0).cell_value ();
1462 str =
Cell (args(0));
1464 if (args(1).iscell ())
1465 pat = args(1).cell_value ();
1467 pat =
Cell (args(1));
1469 if (args(2).iscell ())
1470 rep = args(2).cell_value ();
1472 rep =
Cell (args(2));
1475 if (pat.
numel () != 1)
1478 if (rep.
numel () != 1 && dv1 != rep.
dims ())
1479 error (
"regexprep: inconsistent cell array dimensions");
1481 else if (rep.
numel () != 1)
1489 new_args(0) = str(i);
1490 if (pat.
numel () == 1)
1491 new_args(1) = pat(0);
1492 if (rep.
numel () == 1)
1493 new_args(2) = rep(0);
1497 if (pat.
numel () != 1)
1498 new_args(1) = pat(j);
1499 if (rep.
numel () != 1)
1500 new_args(2) = rep(j);
1504 ret(i) = new_args(0);
1507 retval = (args(0).iscell () ?
ovl (ret) :
ovl (ret(0)));
charNDArray min(char d, const charNDArray &m)
octave_idx_type numel(void) const
Number of elements in the array.
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Vector representing the dimensions (size) of an Array.
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
void assign(const std::string &k, const Cell &val)
const_iterator begin(void) const
Cell cell_value(void) const
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
octave_idx_type length(void) const
octave_idx_type numel(void) const
OCTINTERP_API void print_usage(void)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void error(const char *fmt,...)
ColumnVector transform(const Matrix &m, double x, double y, double z)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
static octave_value_list octregexp(const octave_value_list &args, int nargout, const std::string &who, bool case_insensitive=false)
static void parse_options(regexp::opts &options, const octave_value_list &args, const std::string &who, int skip, bool &extra_args)
static OCTAVE_NAMESPACE_BEGIN std::string do_regexp_ptn_string_escapes(const std::string &s, bool is_sq_str)
static octave_value octregexprep(const octave_value_list &args, const std::string &who)
static std::string do_regexp_rep_string_escapes(const std::string &s)
static octave_value_list octcellregexp(const octave_value_list &args, int nargout, const std::string &who, bool case_insensitive=false)