syntax error at monthly_orders.pl line 1822, near "$"
The regular expression ignores everything up to at . Then it finds monthly_orders.pl , the filename, as the match to the first subexpression " [^ \n]+
" (one or more nonblank, nonnewline characters), and it finds 1822, the line number, as the match to the second subexpression " [0-9]+
" (one or more digits).
For the most part, these regular expressions are documented pretty well in their definitions. Understanding them in depth can still be a challenge, and writing them even more so! Suppose we want to tackle Example 5 by adding an element to this list for our new C++ compiler that prints error messages in German. In particular, it prints error messages like this:
Fehler auf Zeile linenum in filename : text of error message
Here is the element we would add to compilation-error-regexp-alist:
("Fehler auf Zeile \\([0-9]+\\) in \\([^: \t]+\\):" 2 1)
In this case, the second parenthesized subexpression matches the filename, and the first matches the line number.
To add this to compilation-error-regexp-alist, we need to put this line in .emacs :
(setq compilation-error-regexp-alist
(cons '("Fehler auf Zeile \\([0-9]+\\) in \\([^: \t]+\\):" 2 1)
compilation-error-regexp-alist))
Notice how this example resembles our example (from Chapter 9) of adding support for a new language mode to auto-mode-alist.
11.3.2.5 Regular expression operator summary
Table 11-6concludes our discussion of regular expression operators with a reference list of all the operators covered.
Table 11-6. Regular expression operators
Operator |
Function |
. |
Match any character. |
* |
Match 0 or more occurrences of preceding char or group. |
+ |
Match 1 or more occurrences of preceding char or group. |
? |
Match 0 or 1 occurrences of preceding char or group. |
[...] |
Set of characters; see below. |
\\( |
Begin a group. |
\\) |
End a group. |
\\| |
Match the subexpression before or after \\|. |
^ |
At beginning of regexp, match beginning of line or string. |
$ |
At end of regexp, match end of line or string. |
\n |
Match Newline within a regexp. |
\t |
Match Tab within a regexp. |
\\< |
Match beginning of word. |
\\> |
Match end of word. |
The following operators are meaningful within character sets : |
|
^ |
At beginning of set, treat set as chars not to match. |
- (dash) |
Specify range of characters. |
The following is also meaningful in regexp replace strings : |
|
\\ n |
Substitute portion of match within the n th \\( and \\) , counting from left \\( to right, starting with 1. |
Finally, the following characters are operators (not discussed here) when double-backslash-escaped: b
, B
, c
, C
, w
, W
, s
, S
, =
, _
, '
, and `
. Thus, these are "booby traps" when double-backslash-escaped. Some of these behave similarly to the character class aliases you may have encountered in Perl and Java regular expressions.
11.3.3 A Treasure Trove of Examples
As mentioned above, the full auto-mode-alisthas a lot more entries and documentation than fit in this book. The compile.el module in which it is defined also contains functions that use it. One of the best ways to learn how to use Emacs Lisp (as well as discovering things you might not have even realized you can do) is to browse through the implementations of standard modules that are similar to what you're trying to achieve, or that are simply interesting. But how do you find them?
The manual way is to look at the value of the variable load-path. This is the variable Emacs consults when it needs to load a library file itself, so any library you're looking for must be in one of these directories. (This variable is discussed further in the final section of this chapter.) The problem, as you will see if you look at the current value of the variable, is that it contains a large number of directories for you to wade through, which would be pretty tedious each time you're curious about a library. (An easy way to see the variable's value is through Help's "Describe variable" feature, C-h v.)
One of the authors wrote the command listed in Example 11-1to address this problem and uses it regularly to easily snoop on the source files that make much of Emacs run. If you don't want to type this entire function into your .emacs by hand, you can download it from this book's web site, http://www.oreilly.com/catalog/gnu3.
Example 11-1. find-library-file
(defun find-library-file (library)
"Takes a single argument LIBRARY, being a library file to search for.
Searches for LIBRARY directly (in case relative to current directory,
or absolute) and then searches directories in load-path in order. It
will test LIBRARY with no added extension, then with .el, and finally
with .elc. If a file is found in the search, it is visited. If none
is found, an error is signaled. Note that order of extension searching
is reversed from that of the load function."
(interactive "sFind library file: ")
(let ((path (cons "" load-path)) exact match elc test found)
(while (and (not match) path)
(setq test (concat (car path) "/" library)
match (if (condition-case nil
(file-readable-p test)
(error nil))
test)
path (cdr path)))
(setq path (cons "" load-path))
(or match
(while (and (not elc) path)
(setq test (concat (car path) "/" library ".elc")
elc (if (condition-case nil
(file-readable-p test)
(error nil))
test)
path (cdr path))))
(setq path (cons "" load-path))
(while (and (not match) path)
(setq test (concat (car path) "/" library ".el")
match (if (condition-case nil
(file-readable-p test)
(error nil))
test)
path (cdr path)))
(setq found (or match elc))
(if found
(progn
(find-file found)
(and match elc
(message "(library file %s exists)" elc)
(sit-for 1))
(message "Found library file %s" found))
(error "Library file \"%s\" not found." library))))
Once this command is defined, you can visit any library's implementation by typing M-x find-library file Enter libraryname
Enter. If you use it as often as this author does, you too may find it worth binding to a key sequence. We won't present a detailed discussion of how this function works because it goes a bit deeper than this chapter, but if you're curious about what some of the functions do, you can put your cursor in the function name in a Lisp buffer and use the Help system's "Describe function" ( C-h f) feature to get more information about it.
Читать дальше