【发布时间】:2012-08-04 13:28:18
【问题描述】:
我正在寻找 最快 例程(非交互式)来获取字符串中正则表达式的匹配数。
类似
(count-occurrences "a" "alabama")
=> 4
【问题讨论】:
我正在寻找 最快 例程(非交互式)来获取字符串中正则表达式的匹配数。
类似
(count-occurrences "a" "alabama")
=> 4
【问题讨论】:
我可能会这样做:
(defun count-occurrences (regexp string)
"Return the number of occurrences of REGEXP in STRING."
(let ((count 0))
(with-temp-buffer
(save-excursion (insert string))
(while (re-search-forward regexp nil t)
(cl-incf count)))
count))
【讨论】:
(insert string),但实际上re-search-forward 似乎比使用string-match 慢得多(至少相对而言),这让我感到惊讶。不过,我的测试非常粗略,因此不同的输入可能会产生不同的结果。
这里是一个不使用栈的emacs-lisp函数
(defun count-occurences-in-string (pattern string)
"Count occurences of PATTERN in STRING."
(let ((occurences 0)
(start 0)
(length (length string)))
(while (and
(< start length)
(string-match pattern string start))
(setq occurences (1+ occurences))
(setq start (match-end 0)))
occurences))
【讨论】:
如果创建变量副本没有任何问题,可以尝试
(- (length (split-string "Hello World" "o")) 1)
(- (length (split-string "aaabaaa" "a")) 1)
(- (length (split-string "This
string
has three
newlines" "
")) 1)
2
6
3
如果你加载cl-lib包没有问题,那么你可以试试
(require 'cl-lib)
(cl-count ?o "Hello World")
(cl-count ?a "aaabaaa")
(cl-count ?
"This
string
has three
newlines")
2
6
3
【讨论】:
在包s中,有函数s-count-matches。
【讨论】:
这是使用递归和累加器的更实用的答案。作为一个额外的好处,它不使用cl:
(defun count-occurences (regex string)
(recursive-count regex string 0))
(defun recursive-count (regex string start)
(if (string-match regex string start)
(+ 1 (recursive-count regex string (match-end 0)))
0))
【讨论】:
(defun count-occurences (regex string) (recursive-count regex string 0 0)) (defun recursive-count (regex string start counter) (if (string-match regex string start) (recursive-count regex string (match-end 0) (+ counter 1)) counter))
how-many(别名为count-matches)这样做,但适用于缓冲区。
这是一种适用于字符串的方法:
(defun how-many-str (regexp str)
(loop with start = 0
for count from 0
while (string-match regexp str start)
do (setq start (match-end 0))
finally return count))
【讨论】:
loop 是一个宏,完全编译,没有问题。
count-matches 以交互方式进行。也许是一个开始寻找的好地方。
【讨论】: