aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2020-02-11 13:23:10 +0100
committerMattias EngdegÄrd2020-02-12 11:20:47 +0100
commit5a21aaff468ec3f0337117707cda4254cbef8de7 (patch)
tree0afe3c99c133c701c549ee20cb2073a90aa0dc25
parent2b12c2b6f22187536f54f32b11589bf5f21c1f09 (diff)
downloademacs-5a21aaff468ec3f0337117707cda4254cbef8de7.tar.gz
emacs-5a21aaff468ec3f0337117707cda4254cbef8de7.zip
rx: Use longest match for all-string 'or' forms (bug#37659)
Revert to the Emacs 26 semantics that always gave the longest match for rx 'or' forms with only string arguments. This guarantee was never well documented, but it is useful and people likely have come to rely on it. For example, prior to this change, (rx (or ">" ">=")) matched ">" even if the text contained ">=". * lisp/emacs-lisp/rx.el (rx--translate-or): Don't tell regexp-opt to preserve the matching order. * doc/lispref/searching.texi (Rx Constructs): Document the longest-match guarantee for all-string 'or' forms. * test/lisp/emacs-lisp/rx-tests.el (rx-or): Update test.
-rw-r--r--doc/lispref/searching.texi5
-rw-r--r--lisp/emacs-lisp/rx.el2
-rw-r--r--test/lisp/emacs-lisp/rx-tests.el2
3 files changed, 6 insertions, 3 deletions
diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi
index 3d7ea932863..5f4509a8b43 100644
--- a/doc/lispref/searching.texi
+++ b/doc/lispref/searching.texi
@@ -1080,7 +1080,10 @@ Corresponding string regexp: @samp{@var{A}@var{B}@dots{}}
1080@cindex @code{or} in rx 1080@cindex @code{or} in rx
1081@itemx @code{(| @var{rx}@dots{})} 1081@itemx @code{(| @var{rx}@dots{})}
1082@cindex @code{|} in rx 1082@cindex @code{|} in rx
1083Match exactly one of the @var{rx}s, trying from left to right. 1083Match exactly one of the @var{rx}s.
1084If all arguments are string literals, the longest possible match
1085will always be used. Otherwise, either the longest match or the
1086first (in left-to-right order) will be used.
1084Without arguments, the expression will not match anything at all.@* 1087Without arguments, the expression will not match anything at all.@*
1085Corresponding string regexp: @samp{@var{A}\|@var{B}\|@dots{}}. 1088Corresponding string regexp: @samp{@var{A}\|@var{B}\|@dots{}}.
1086 1089
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 03af053c91e..b4cab5715da 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -290,7 +290,7 @@ Return (REGEXP . PRECEDENCE)."
290 ((null (cdr body)) ; Single item. 290 ((null (cdr body)) ; Single item.
291 (rx--translate (car body))) 291 (rx--translate (car body)))
292 ((rx--every #'stringp body) ; All strings. 292 ((rx--every #'stringp body) ; All strings.
293 (cons (list (regexp-opt body nil t)) 293 (cons (list (regexp-opt body nil))
294 t)) 294 t))
295 ((rx--every #'rx--charset-p body) ; All charsets. 295 ((rx--every #'rx--charset-p body) ; All charsets.
296 (rx--translate-union nil body)) 296 (rx--translate-union nil body))
diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el
index e19e626527b..a6c172adfe7 100644
--- a/test/lisp/emacs-lisp/rx-tests.el
+++ b/test/lisp/emacs-lisp/rx-tests.el
@@ -43,7 +43,7 @@
43 (should (equal (rx (or "ab" (| "c" nonl) "de")) 43 (should (equal (rx (or "ab" (| "c" nonl) "de"))
44 "ab\\|c\\|.\\|de")) 44 "ab\\|c\\|.\\|de"))
45 (should (equal (rx (or "ab" "abc" "a")) 45 (should (equal (rx (or "ab" "abc" "a"))
46 "\\(?:ab\\|abc\\|a\\)")) 46 "\\(?:a\\(?:bc?\\)?\\)"))
47 (should (equal (rx (| nonl "a") (| "b" blank)) 47 (should (equal (rx (| nonl "a") (| "b" blank))
48 "\\(?:.\\|a\\)\\(?:b\\|[[:blank:]]\\)")) 48 "\\(?:.\\|a\\)\\(?:b\\|[[:blank:]]\\)"))
49 (should (equal (rx (|)) 49 (should (equal (rx (|))