[英]How do I count the number of specific characters in a string in Emacs Lisp?
Let's say I have a string s.假设我有一个字符串 s。
And this string s could contain this:这个字符串 s 可以包含这个:
asdf-asdfasdfasf-fasdf-asdfasdfasdf
or this:或这个:
asf-asdfaf
but also this:还有这个:
aasdaf
How do I count the number of dashes (-) in this string using Emacs Lisp and store this number in some variable eg count-of-dashes?如何使用 Emacs Lisp 计算此字符串中的破折号 (-) 的数量,并将此数字存储在某个变量中,例如破折号计数?
The following function should do it:以下 function 应该这样做:
(defun count-chars (char str)
(let ((s (char-to-string char))
(count 0)
(start-pos -1))
(while (setq start-pos (string-search s str (+ 1 start-pos)))
(setq count (+ 1 count)))
count))
You call it like this:你这样称呼它:
(count-chars ?- "---") ==> 3
(count-chars ?- "foo-bar") ==> 1
(count-chars ?- "-foo-bar-baz") ==> 3
(count-chars ?- "foobarbaz") ==> 0
To set a variable to the number found, you just use setq
:要将变量设置为找到的数字,只需使用
setq
:
(setq count-of-chars (count-chars ?- "foo-bar-baz"))
Basically, we loop looking for the first dash: if we find it we remember where so that we start looking at the place just to the right of it the next time around the loop.基本上,我们循环寻找第一个破折号:如果找到它,我们会记住在哪里,以便我们在下一次循环时开始查看它右侧的位置。 The loop body then just counts every one we see.
然后循环体只计算我们看到的每一个。 When we can't find any more,
string-search
(and the setq
) returns nil
and the loop exits, whereupon we return the accumulated count
.当我们找不到更多时,
string-search
(和setq
)返回nil
并且循环退出,然后我们返回累积的count
。 See the doc string of the function string-search
with Ch f string-search
for the details.有关详细信息,请参阅 function
string-search
和Ch f string-search
的文档字符串。
Another method is more akin to the split
string method of python: split-string
splits a string on a separator into a list of parts.另一种方法更类似于 python 的
split
字符串方法: split-string
将分隔符上的字符串拆分为部分列表。 We then count the parts (the length of the list) and subtract 1: "abc"
is split into ("a" "b" "c")
so there are three parts but only two separators.然后我们计算部分(列表的长度)并减去 1:
"abc"
被拆分为("a" "b" "c")
,所以有三个部分,但只有两个分隔符。
(defun count-chars (char str)
(let ((s (char-to-string char)))
(- (length (split-string str s)) 1)))
Again, see the doc string of split-string
( Ch f split-string
) for all the details.再次,请参阅
split-string
( Ch f split-string
) 的文档字符串以了解所有详细信息。
In both cases, we converted the character argument to a string argument, because both string-search
in the first case and split-string
in the second expect a string argument (to search for in the first case and to use as a separator in the second case - in fact, split-string
can use a regular expression as a separator).在这两种情况下,我们都将字符参数转换为字符串参数,因为第一种情况下的
string-search
和第二种情况下的split-string
都需要一个字符串参数(在第一种情况下搜索并用作分隔符第二种情况——实际上, split-string
可以使用正则表达式作为分隔符)。 Characters and strings are different data types in Emacs Lisp, so the conversion is necessary if you really want a character s the first argument of count-chars
.字符和字符串在 Emacs Lisp 中是不同的数据类型,所以如果你真的想要一个字符作为
count-chars
的第一个参数,那么转换是必要的。 But you could make it a string instead:但是你可以把它变成一个字符串:
(defun count-seps (sep str)
(- (length (split-string str sep)) 1))
and then you would call it like this instead:然后你会这样称呼它:
(count-seps "-" "abc-def-ghi-")
which is simpler and more general:这更简单,更通用:
(count-seps "-;-" "abc-;-def") ==> 1
but you do have to worry about special characters in the separator string:但是您必须担心分隔符字符串中的特殊字符:
(count-seps "-*-" "abcd-------def") ==> 1
since the regular expression -*-
matches one or more dashes so it matches all seven dashes: there is only one separator.因为正则表达式
-*-
匹配一个或多个破折号,所以它匹配所有七个破折号:只有一个分隔符。 Whether that's what you want is debatable.这是否是你想要的还有待商榷。 If you don't want it, you'd need to escape the special characters in the separator string:
如果您不想要它,则需要转义分隔符字符串中的特殊字符:
(defun count-chars (sep str)
(let ((qsep (regexp-quote sep)))
(- (length (split-string str qsep)) 1)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.