Function: match-data
match-data is a function defined in search.c.
Signature
(match-data &optional INTEGERS REUSE RESEAT)
Documentation
Return a list of positions that record text matched by the last search.
Element 2N of the returned list is the position of the beginning of the
match of the Nth subexpression; it corresponds to (match-beginning N);
element 2N + 1 is the position of the end of the match of the Nth
subexpression; it corresponds to (match-end N). See match-beginning
and match-end.
If the last search was on a buffer, all the elements are by default
markers or nil (nil when the Nth pair didn't match); they are integers
or nil if the search was on a string. But if the optional argument
INTEGERS is non-nil, the elements that represent buffer positions are
always integers, not markers, and (if the search was on a buffer) the
buffer itself is appended to the list as one additional element.
Use set-match-data to reinstate the match data from the elements of
this list.
Note that non-matching optional groups at the end of the regexp are
elided instead of being represented with two nils each. For instance:
(progn
(string-match "^\\(a\\)?\\(b\\)\\(c\\)?$" "b")
(match-data))
=> (0 1 nil nil 0 1)
If REUSE is a list, store the value in REUSE by destructively modifying it. If REUSE is long enough to hold all the values, its length remains the same, and any unused elements are set to nil. If REUSE is not long enough, it is extended. Note that if REUSE is long enough and INTEGERS is non-nil, no consing is done to make the return value; this minimizes GC.
If optional third argument RESEAT is non-nil, any previous markers on the REUSE list will be modified to point to nowhere.
Return value is undefined if the last search failed.
Probably introduced at or before Emacs version 22.1.
Source Code
// Defined in /usr/src/emacs/src/search.c
{
Lisp_Object tail, prev;
Lisp_Object *data;
ptrdiff_t i, len;
if (!NILP (reseat))
for (tail = reuse; CONSP (tail); tail = XCDR (tail))
if (MARKERP (XCAR (tail)))
{
unchain_marker (XMARKER (XCAR (tail)));
XSETCAR (tail, Qnil);
}
if (NILP (last_thing_searched))
return Qnil;
prev = Qnil;
USE_SAFE_ALLOCA;
SAFE_NALLOCA (data, 1, 2 * search_regs.num_regs + 1);
len = 0;
for (i = 0; i < search_regs.num_regs; i++)
{
ptrdiff_t start = search_regs.start[i];
if (start >= 0)
{
if (BASE_EQ (last_thing_searched, Qt)
|| ! NILP (integers))
{
XSETFASTINT (data[2 * i], start);
XSETFASTINT (data[2 * i + 1], search_regs.end[i]);
}
else if (BUFFERP (last_thing_searched))
{
data[2 * i] = Fmake_marker ();
Fset_marker (data[2 * i],
make_fixnum (start),
last_thing_searched);
data[2 * i + 1] = Fmake_marker ();
Fset_marker (data[2 * i + 1],
make_fixnum (search_regs.end[i]),
last_thing_searched);
}
else
/* last_thing_searched must always be Qt, a buffer, or Qnil. */
emacs_abort ();
len = 2 * i + 2;
}
else
data[2 * i] = data[2 * i + 1] = Qnil;
}
if (BUFFERP (last_thing_searched) && !NILP (integers))
{
data[len] = last_thing_searched;
len++;
}
/* If REUSE is not usable, cons up the values and return them. */
if (! CONSP (reuse))
reuse = Flist (len, data);
else
{
/* If REUSE is a list, store as many value elements as will fit
into the elements of REUSE. */
for (i = 0, tail = reuse; CONSP (tail);
i++, tail = XCDR (tail))
{
if (i < len)
XSETCAR (tail, data[i]);
else
XSETCAR (tail, Qnil);
prev = tail;
}
/* If we couldn't fit all value elements into REUSE,
cons up the rest of them and add them to the end of REUSE. */
if (i < len)
XSETCDR (prev, Flist (len - i, data + i));
}
SAFE_FREE ();
return reuse;
}