'string-match'在'org-map-entries'中不起作用

时间:2013-07-27 20:11:27

标签: regex emacs org-mode

我正在尝试映射文件中的所有组织条目,并收集标题的一部分(如果它与某些正则表达式匹配)。

问题是字符串匹配总是返回nil。当我逐步使用edebug时,我可以看到其他一切都正常工作。

在这里,我尽可能地减少了问题:

(defun test ()
  (let ((found nil))
    (org-map-entries (lambda ()
               (let ((heading (org-get-heading t t)))
             (when (string-match "[ \t]*>>>[ \t]*\\([A-Z0-9_-]+\\)"
                         heading)
               (push (match-string 1 heading) found))))

             nil '("test.org"))
    found))

test.org中的3行:

* >>> one
* two
* >>> three

字符串匹配工作正常:

(string-match "[ \t]*>>>[ \t]*\\([A-Z0-9_-]+\\)" ">>> one")
=> 0

我尝试过的一些事情:
  - 匹配前删除字符串属性。
  - 实现围绕重新搜索 - 转发。
  - 将正则表达式匹配移动到单独的函数。
  - 用'mapcar'替换'org-map-entries'并在列表上进行测试,工作正常。

我正在使用GNU Emacs 24.3.1(x86_64-unknown-linux-gnu,GTK + 3.4.2版)

任何提示都会非常感激。

3 个答案:

答案 0 :(得分:3)

提示:使用org-element!至少如果使用Org v8 +是可行的。

这是一个可以构建的玩具示例。将其复制到Org缓冲区并评估代码块。

编辑:更多示例。基本上,我无法重现。查看test功能的最后一个标题。

* >>> one
#+begin_src emacs-lisp :file test2.org
  (save-excursion (find-file "test2.org")
                  (delete-region (point-min) (point-max))
                  (insert "* >>> one2\n* two2"))
#+end_src

#+RESULTS:
[[file:test2.org]]

A function
#+begin_src emacs-lisp
  (defun my/tagged-headings (&optional regexp file full-element)
    "Return headings matching regexp.  If simple is t return only the headline.  Else return the element.  Requires Org-Element (Org>8)"
    (require 'org-element)
    (save-excursion
      (when (and file (file-exists-p file))
        (find-file file))
      (let (found
            (regexp (if regexp regexp "^>>>")))
        (org-element-map
            (org-element-parse-buffer)
            'headline
          '(lambda (h)
             (when  (string-match "^>>>" (org-element-property :raw-value h))
               (push (if full-element h (org-element-property :raw-value h)) found))))
        found)))
#+end_src

#+begin_src emacs-lisp
(my/tagged-headings)
#+end_src

#+RESULTS:
| >>> three | >>> one |

#+begin_src emacs-lisp
(my/tagged-headings nil "test2.org")
#+end_src

#+RESULTS:
| >>> one2 |

* two

#+begin_src emacs-lisp
  (defun my/tagged-headings2 ()
    (let (found)
      (org-map-entries (lambda () 
                         (save-excursion
                           (when (search-forward-regexp "^*+[[:space:]]*>+" (point-at-eol) t)
                             (push (org-get-heading t t) found)
                             ))))
      found))
#+end_src


#+begin_src emacs-lisp 
(my/tagged-headings2)
#+end_src

#+RESULTS:
| >>> three | >>> one |


* >>> three 



#+begin_src emacs-lisp
  (defun test (&optional file)
    (save-excursion
      (when (and file (file-exists-p file)) (find-file file))
      (let ((found nil))
        (org-map-entries (lambda ()
                           (let ((heading (org-get-heading t t)))
                             (when (string-match "[ \t]*>>>[ \t]*\\([A-Z0-9_-]+\\)"
                                                 heading)
                               (push (match-string 1 heading) found)))))
        found)))
#+end_src

#+begin_src emacs-lisp
(test)
#+end_src

#+RESULTS:
| three | one |

#+begin_src emacs-lisp
(test "test2.org")
#+end_src

#+RESULTS:
| one2 |

答案 1 :(得分:3)

当代码运行时,case-fold-search可能会以某种方式设置为nil吗?因此“A-Z”不再与小写字符匹配)?如果是这样,则将A-Z0-9替换为[:alnum:]应该可以解决问题。

答案 2 :(得分:0)

我从一开始就得到了正确的结果。 Emacs 24.3.4。组织模式版本8.0.6。 您应该更新您的设置。