如何查找包含特定子字符串的列表项



我有一个字符串列表,fx '("abc" "def" "gih"),我希望能够在列表中搜索包含fx "ef"的任何项目并获取返回的项目或索引。

这是怎么做到的?

结合filterre-find可以很好地做到这一点。

user> (def fx '("abc" "def" "gih")) 
#'user/fx
user> (filter (partial re-find #"ef") fx)
("def")
user> (filter (partial re-find #"a") fx)
("abc")

在这种情况下,我喜欢将它们与partial结合起来,尽管在这种情况下定义匿名函数也可以正常工作。如果您事先不知道搜索字符串,使用 re-pattern 也很有用:

user> (filter (partial re-find (re-pattern "a")) fx)
("abc")

如果你想检索匹配位置的所有索引以及元素,你可以试试这个:

(filter #(re-find #"ef" (second %)) (map-indexed vector '("abc" "def" "gih")))
=>([1 "def"])

map-indexed vector生成索引/值延迟序列

user> (map-indexed vector '("abc" "def" "gih"))
  ([0 "abc"] [1 "def"] [2 "gih"])

然后,您可以对每个列表成员的 second 元素使用正则表达式来filter

 #(re-find #"ef" (second %))

只是索引:

  • 懒洋洋 地:

    (keep-indexed #(if (re-find #"ef" %2)
                      %1) '("abc" "def" "gih"))
    => (1)
    
  • 使用循环/重复

    (loop [[str & strs] '("abc" "def" "gih")
           idx 0
           acc []]
      (if str
        (recur strs
               (inc idx)
               (cond-> acc
                 (re-find #"ef" str) (conj idx)))
        acc))
    

    有关元素,请参阅Arthur Ulfeldts的答案。

下面是返回索引的传统递归定义。 修改以返回相应的字符串也很容易。

(defn strs-index [re lis] 
  (let [f (fn [ls n] 
             (cond 
               (empty? ls) nil 
               (re-find re (first ls)) n
               :else (recur (rest ls) (inc n))))]
    (f lis 0)))
user=> (strs-index #"de" ["abc" "def" "gih"])
1
user=> (strs-index #"ih" ["abc" "def" "gih"])
2
user=> (strs-index #"xy" ["abc" "def" "gih"])
nil

(说明:帮助程序函数flet 中定义为绑定,然后在末尾调用。 如果传递给它的字符串序列不为空,它将在序列的第一个元素中搜索正则表达式,如果找到字符串,则返回索引。 这利用了这样一个事实,即 re-find 的结果除非失败,否则将计为 true,在这种情况下,它返回 nil 。 如果前面的步骤不成功,函数将使用序列的其余部分和递增的索引重新开始。 如果它到达序列的末尾,则返回 nil。