我有一个名为F的字符串列表:
("hello word i'am walid" "goodbye madame")
=>此列表包含两个字符串
我有另一个列表调用S这样("word" "madame")
=>这包含两个单词
现在我想从列表F的每个字符串中删除列表S的元素,输出应该像这样("hello i'am walid" "goodbye")
(defun remove-string (rem-string full-string &key from-end (test #'eql)
test-not (start1 0) end1 (start2 0) end2 key)
"returns full-string with rem-string removed"
(let ((subst-point (search rem-string full-string
:from-end from-end
:test test :test-not test-not
:start1 start1 :end1 end1
:start2 start2 :end2 end2 :key key)))
(if subst-point
(concatenate 'string
(subseq full-string 0 subst-point)
(subseq full-string (+ subst-point (length rem-string))))
full-string)))
例如:
(remove-string "walid" "hello i'am walid")
=>输出"hello i'am"
但是有问题
例如:
(remove-string "wa" "hello i'am walid")
=>输出"hello i'am lid"
但是输出应该像这个"hello i'am walid"
在另一个词中我不会从字符串中删除确切的单词
请帮帮我,谢谢
答案 0 :(得分:3)
您可以将cl-ppcre
库用于正则表达式。它的正则表达式风格理解单词边界\b
。
替换可以这样工作:
(cl-ppcre:regex-replace-all "\\bwa\\b" "ba wa walid" "")
=> "ba walid"
我想你想要将删除的单词周围的任何空格折叠成一个:
(cl-ppcre:regex-replace-all "\\s*\\bwa\\b\\s*" "ba wa walid" " ")
=> "ba walid"
请参阅上面链接的文档。
更新:您将问题扩展为标点符号。这实际上有点复杂,因为你现在有三种字符:字母数字,标点符号和空格。
我不能在这里提供完整的解决方案,但我设想的大纲是在所有这三种类型之间创建边界定义。你需要正面/负面的前瞻/外观。然后你看看被替换的字符串,无论是以标点符号开头还是结尾,并将相应的边界附加或附加到有效表达式。
为了以可读的方式定义边界,cl-ppcre的解析树语法可能证明是有用的。
答案 1 :(得分:1)
Common Lisp Cookbook提供此功能:
(defun replace-all (string part replacement &key (test #'char=))
"Returns a new string in which all the occurences of the part
is replaced with replacement."
(with-output-to-string (out)
(loop with part-length = (length part)
for old-pos = 0 then (+ pos part-length)
for pos = (search part string
:start2 old-pos
:test test)
do (write-string string out
:start old-pos
:end (or pos (length string)))
when pos do (write-string replacement out)
while pos)))
使用该功能:
(loop for raw-string in '("hello word i'am walid" "goodbye madame")
collect (reduce (lambda (source-string bad-word)
(replace-all source-string bad-word ""))
'("word" "madame")
:initial-value raw-string))