: Learning GNU Emacs, 3rd Edition

11.3.4 Functions That Use Regular Expressions

11.3.4 Functions That Use Regular Expressions

The functions re-search-forward, re-search-backward, replace-regexp, query-replace-regexp, highlight-regexp, isearch-forward-regexp, and isearch-backward-regexp are all user commands that use regular expressions, and they can all be used within Lisp code (though it is hard to imagine incremental search being used within Lisp code). The section on customizing major modes later in this chapter contains an example function that uses re-search-forward. To find other commands that use regexps you can use the "apropos" help feature (C-h a regexp Enter).

Other such functions aren't available as user commands. Perhaps the most widely used one is looking-at. This function takes a regular expression argument and does the following: it returns t if the text after point matches the regular expression (nil otherwise); if there was a match, it saves the pieces surrounded by ( and ) for future use, as seen earlier. The function string-match is similar: it takes two arguments, a regexp and a string. It returns the starting index of the portion of the string that matches the regexp, or nil if there is no match.

The functions match-beginning and match-end can be used to retrieve the saved portions of the matched string. Each takes as an argument the number of the matched expression (as in n in replace-regexp replace strings) and returns the character position in the buffer that marks the beginning (for match-beginning) or end (for match-end) of the matched string. With the argument 0, the character position that marks the beginning/end of the entire string matched by the regular expression is returned.

Two more functions are needed to make the above useful: we need to know how to convert the text in a buffer to a string. No problem: buffer-string returns the entire buffer as a string; buffer-substring takes two integer arguments, marking the beginning and end positions of the substring desired, and returns the substring.

With these functions, we can write a bit of Lisp code that returns a string containing the portion of the buffer that matches the nth parenthesized subexpression:

(buffer-substring (match-beginning n (match-end n)))

In fact, this construct is used so often that Emacs has a built-in function, match-string, that acts as a shorthand; (match-string n) returns the same result as in the previous example.

An example should show how this capability works. Assume you are writing the Lisp code that parses compiler error messages, as in our previous example. Your code goes through each element in compilation-error-regexp-alist, checking if the text in a buffer matches the regular expression. If it matches, your code needs to extract the filename and the line number, visit the file, and go to the line number.

Although the code for going down each element in the list is beyond what we have learned so far, the routine basically looks like this:

for each element in compilation-error-regexp-alist
(let ((regexp the regexp in the element)
(file-subexp the number of the filename subexpression)
(line-subexp the number of the line number subexpression))
(if (looking-at regexp)
(let ((filename (match-string file-subexp))
(linenum (match-string line-subexp)))
(find-file-other-window filename)
(goto-line linenum))
(otherwise, try the next element in the list)))

The second let extracts the filename from the buffer from the beginning to the end of the match to the file-subexp-th subexpression, and it extracts the line number similarly from the line-subexp-th subexpression (and converts it from a string to a number). Then the code visits the file (in another window, not the same one as the error message buffer) and goes to the line number where the error occurred.

The code for the calculator mode later in this chapter contains a few other examples of looking-at, match-beginning, and match-end.

: 0.756. /Cache: 0 / 0