假设我有一个字符串s
和一个字符串ts
的元组列表,其中元组中的第一个元素是s
的子字符串我想要替换与相应的第二个元素。在我的例子中,字符串s
将始终是以空格分隔的不同单词列表;此外,我希望将s
中的每个单词全部替换为ts
中的相应值(我希望我的意图在此处清楚)。第一次尝试可能是:
import qualified Text.Regex as R -- from regex-compat
replaceAllIn :: String -> [(String, String)] -> String
replaceAllIn = foldl (\acc, (k, v) -> R.subRegex (R.makeRegex k) acc v)
当一个键是另一个键的子串时,这当然不起作用
λ> s = "blah blahblee"
λ> ts = [("blah", "asdf"), ("blahblee", ";lkj")]
λ> replaceAllIn s ts
"asdf asdfblee"
因为第一个键替换了" blah"在第一次通过时,留下一条不再有任何匹配的字符串" blahblee"第二次传球
有没有办法在一次通过字符串时实现我想要的东西?或者是否有一种内置方式(在某些库中某处)可以一次替换多个模式?
编辑:发布后我立即意识到我不知道为什么我在这里使用正则表达式。但是如果我用MissingH的Data.String.Utils中的replace
替换正则表达式替换,问题仍然有效。
答案 0 :(得分:2)
扩展我之前的评论,您可以先处理要替换的最长字符串:
# query the table and select id, derivable_type and derivable_id
my_table_ids = MyTable
.group("derivable_type, derivable_id")
.select("MAX(id) AS my_table_id, derivable_type, derivable_id")
# use subquery to allow rails to use ORDER BY in find_each
MyTable
.where(id: my_table_ids.select('my_table_id'))
.find_each { |row| do_something(row) }
答案 1 :(得分:1)
就我而言,字符串
s
将始终是以空格分隔的不同单词列表;此外,我希望完整地替换s
中的每个单词
我看到的第一步是将字符串拆分(或分隔)为空格。
接下来,正如@keuhlen建议的那样,我将替换对从最长到最短排序。
之后,问题应该很简单,并且子串搜索速度很快,因为它会通过字边界前进。
(一个额外的优化可能是按照长度对搜索模式进行分组,例如在树或数组中,这样对于较短的输入单词,从不考虑更长的模式。)