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.

View in manual

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;
}