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.}.
@c E.g., see http://debbugs.gnu.org/2816
If the optional argument @var{paren} is non-@code{nil}, then the
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).
The optional argument @var{paren} can be any of the following:
This simplified definition of @code{regexp-opt} produces a
regular expression which is equivalent to the actual value
(but not as efficient):
a string
the resulting regexp is preceded by @var{paren} and followed by
@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
(defun regexp-opt (strings &optional paren)
(let ((open-paren (if paren "\\(" ""))
(close-paren (if paren "\\)" "")))
(concat open-paren
(mapconcat 'regexp-quote strings "\\|")
close-paren)))
(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))))
@end example
@end defun

View file

@ -86,18 +86,44 @@
;;;###autoload
(defun regexp-opt (strings &optional paren)
"Return a regexp to match a string in the list STRINGS.
Each string should be unique in STRINGS and should not contain any regexps,
quoted or not. If optional PAREN is non-nil, ensure that the returned regexp
is enclosed by at least one regexp grouping construct.
The returned regexp is typically more efficient than the equivalent regexp:
Each string should be unique in STRINGS and should not contain
any regexps, quoted or not. Optional PAREN specifies how the
returned regexp is surrounded by grouping constructs.
(let ((open (if PAREN \"\\\\(\" \"\")) (close (if PAREN \"\\\\)\" \"\")))
(concat open (mapconcat \\='regexp-quote STRINGS \"\\\\|\") close))
The optional argument PAREN can be any of the following:
If PAREN is `words', then the resulting regexp is additionally surrounded
by \\=\\< and \\>.
If PAREN is `symbols', then the resulting regexp is additionally surrounded
by \\=\\_< and \\_>."
a string
the resulting regexp is preceded by PAREN and followed by
\\), e.g. use \"\\\\(?1:\" to produce an explicitly numbered
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
;; Recurse on the sorted list.
(let* ((max-lisp-eval-depth 10000)