【发布时间】:2019-08-23 00:34:20
【问题描述】:
假设我有一个字符串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 替换正则表达式替换,问题仍然有效。
【问题讨论】:
-
当字符串包含
"foobarbaz"时,如果你想用"marmoset"替换"foobar",用"barbaz"替换"elephant"会发生什么? -
你能不能先对
ts进行排序以替换最长的字符串? -
@Cirdec 我很抱歉。我的问题还不清楚。编辑以反映在我的情况下不会发生这种情况(元组列表中会有一个“foobarbaz”键)。
-
@jkeuhlen 那应该可以。感谢您的洞察力!
-
错字:lambda 表达式的参数必须用空格而不是逗号分隔,请参阅
\acc,。否则,很好的 Haskell 正则表达式代码。