From 3801c2fb7c75c1d45ea7a126fdfb801ff13de5a4 Mon Sep 17 00:00:00 2001 From: immerrr Date: Sun, 7 Feb 2016 12:46:37 +0300 Subject: [PATCH] Fix regexp-opt documentation (bug #17862) * lisp/emacs-lisp/regexp-opt.el (regexp-opt): update PAREN doc * doc/lispref/searching.texi (Regexp Functions): update PAREN doc --- doc/lispref/searching.texi | 52 ++++++++++++++++++++++++++++--------------- lisp/emacs-lisp/regexp-opt.el | 46 +++++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index 1243d72..e42f630 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -946,26 +946,42 @@ Regexp Functions 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). - -This simplified definition of @code{regexp-opt} produces a -regular expression which is equivalent to the actual value -(but not as efficient): +The optional argument @var{paren} can be any of the following: + +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} + if all @var{strings} are single-character, the resulting regexp is + not surrounded, otherwise it is surrounded by @samp{\(?:} and + @samp{\)}. + +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 diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el index b1e132a..95c6109 100644 --- a/lisp/emacs-lisp/regexp-opt.el +++ b/lisp/emacs-lisp/regexp-opt.el @@ -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 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) -- 2.9.2