Fix regexp-opt documentation (bug #17862)

* lisp/emacs-lisp/regexp-opt.el (regexp-opt):
* doc/lispref/searching.texi (Regexp Functions): Update PAREN doc.
This commit is contained in:
immerrr 2016-02-07 12:46:37 +03:00 committed by Noam Postavsky
parent 803ad6f7e7
commit 56bf7d7e27
2 changed files with 69 additions and 27 deletions

View file

@ -948,26 +948,42 @@ possible. A hand-tuned regular expression can sometimes be slightly
more efficient, but is almost never worth the effort.}. more efficient, but is almost never worth the effort.}.
@c E.g., see http://debbugs.gnu.org/2816 @c E.g., see http://debbugs.gnu.org/2816
If the optional argument @var{paren} is non-@code{nil}, then the The optional argument @var{paren} can be any of the following:
returned regular expression is always enclosed by at least one
parentheses-grouping construct. If @var{paren} is @code{words}, then
that construct is additionally surrounded by @samp{\<} and @samp{\>};
alternatively, if @var{paren} is @code{symbols}, then that construct
is additionally surrounded by @samp{\_<} and @samp{\_>}
(@code{symbols} is often appropriate when matching
programming-language keywords and the like).
This simplified definition of @code{regexp-opt} produces a a string
regular expression which is equivalent to the actual value the resulting regexp is preceded by @var{paren} and followed by
(but not as efficient): @samp{\)}, e.g. use @samp{"\\(?1:"} to produce an explicitly
numbered group.
@code{words}
the resulting regexp is surrounded by @samp{\<\(} and @samp{\)\>}.
@code{symbols}
the resulting regexp is surrounded by @samp{\_<\(} and @samp{\)\_>}
(this is often appropriate when maching programming-language
keywords and the like).
non-@code{nil}
the resulting regexp is surrounded by @samp{\(} and @samp{\)}.
@code{nil}
the resulting regexp is surrounded by @samp{\(?:} and @samp{\)},
if it is necessary to ensure that a postfix operator appended to
it will apply to the whole expression.
The resulting regexp of @code{regexp-opt} is equivalent to but usually
more efficient than that of a simplified version:
@example @example
(defun regexp-opt (strings &optional paren) (defun simplified-regexp-opt (strings &optional paren)
(let ((open-paren (if paren "\\(" "")) (let ((parens (cond ((stringp paren) (cons paren "\\)"))
(close-paren (if paren "\\)" ""))) ((eq paren 'words) '("\\<\\(" . "\\)\\>"))
(concat open-paren ((eq paren 'symbols) '("\\_<\\(" . "\\)\\_>"))
(mapconcat 'regexp-quote strings "\\|") ((null paren) '("\\(?:" . "\\)"))
close-paren))) (t '("\\(" . "\\)")))))
(concat (car paren)
(mapconcat 'regexp-quote strings "\\|")
(cdr paren))))
@end example @end example
@end defun @end defun

View file

@ -86,18 +86,44 @@
;;;###autoload ;;;###autoload
(defun regexp-opt (strings &optional paren) (defun regexp-opt (strings &optional paren)
"Return a regexp to match a string in the list STRINGS. "Return a regexp to match a string in the list STRINGS.
Each string should be unique in STRINGS and should not contain any regexps, Each string should be unique in STRINGS and should not contain
quoted or not. If optional PAREN is non-nil, ensure that the returned regexp any regexps, quoted or not. Optional PAREN specifies how the
is enclosed by at least one regexp grouping construct. returned regexp is surrounded by grouping constructs.
The returned regexp is typically more efficient than the equivalent regexp:
(let ((open (if PAREN \"\\\\(\" \"\")) (close (if PAREN \"\\\\)\" \"\"))) The optional argument PAREN can be any of the following:
(concat open (mapconcat \\='regexp-quote STRINGS \"\\\\|\") close))
If PAREN is `words', then the resulting regexp is additionally surrounded a string
by \\=\\< and \\>. the resulting regexp is preceded by PAREN and followed by
If PAREN is `symbols', then the resulting regexp is additionally surrounded \\), e.g. use \"\\\\(?1:\" to produce an explicitly numbered
by \\=\\_< and \\_>." group.
`words'
the resulting regexp is surrounded by \\=\\<\\( and \\)\\>.
`symbols'
the resulting regexp is surrounded by \\_<\\( and \\)\\_>.
non-nil
the resulting regexp is surrounded by \\( and \\).
nil
the resulting regexp is surrounded by \\(?: and \\), if it is
necessary to ensure that a postfix operator appended to it will
apply to the whole expression.
The resulting regexp is equivalent to but usually more efficient
than that of a simplified version:
(defun simplified-regexp-opt (strings &optional paren)
(let ((parens
(cond ((stringp paren) (cons paren \"\\\\)\"))
((eq paren 'words) '(\"\\\\\\=<\\\\(\" . \"\\\\)\\\\>\"))
((eq paren 'symbols) '(\"\\\\_<\\\\(\" . \"\\\\)\\\\_>\"))
((null paren) '(\"\\\\(?:\" . \"\\\\)\"))
(t '(\"\\\\(\" . \"\\\\)\")))))
(concat (car paren)
(mapconcat 'regexp-quote strings \"\\\\|\")
(cdr paren))))"
(save-match-data (save-match-data
;; Recurse on the sorted list. ;; Recurse on the sorted list.
(let* ((max-lisp-eval-depth 10000) (let* ((max-lisp-eval-depth 10000)