- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想做的是使用正则表达式解析字符串并获取Html元素作为输出,因此函数签名应如下所示:
parse : String -> Html Msg
在我们深入研究代码之前,让我们举一个例子,代码应该如何表现,以便有一个清晰的想法,给定以下字符串:
输入:你好(!BOLD!)我是粗体文本(!BOLD!)bla bla la
预期输出:div [ ][ text "hello", b [ ][ text "I Am a bold text"] , text "bla la la"] ]
为了实现这个目标,我使用了ELM包中提供的正则表达式库
replace : HowMany -> Regex -> (Match -> String) -> String -> String
在上述函数之上,我创建了下面列出的 2 个函数:
myReplace str expression =
replace (All) ( regex expression ) matchToString str
--myreplace "hello (!BOLD!) bold (!BOLD!) " "(!BOLD!)" == "hello b[][] hello"
使用下面的辅助函数,该函数采用 Match 并指定正则表达式的开始和结束
matchToString : Match -> String
matchToString match =
case match.number `rem` 2 of
0 ->"]" -- mtaches the close bracket
_ -> "B [][" --mtaches the open bracket
但我想要得到的是:div [][text "hello", b[][text "bold"]]
如何改进我的代码并编写完整的解析器?或者我如何在 haskell 中实现相同的目的?
最佳答案
在这种情况下,正则表达式开始失去作用并变得过于复杂。相反,我建议查看 Parser Combinators它们功能更强大,同时更易于维护和推理。
在此示例中,我将使用 Bogdanp/elm-combine包。
在这里,我们将构建一个解析器,它接受一个字符串并假设它是无样式的,直到它遇到 (!BOLD!)
并保持粗体,直到找到另一个 (!BOLD!)
条目。输出将是字符元组列表,以及它们是Unstyled
还是Bold
。 警告:可能有更简洁的组合器可以实现此目的,但我对这门艺术相对较新
import Html exposing (..)
import Html.Attributes exposing (..)
import Combine exposing (..)
import Combine.Char exposing (..)
import Combine.Infix exposing (..)
import String
import List.Extra exposing (groupWhile)
type Style
= Unstyled
| Bold
styleParser : Bool -> Parser (List (Char, Style))
styleParser bolded =
let
style = if bolded then Bold else Unstyled
in
(end `andThen` always (succeed []))
<|> (string "(!BOLD!)" `andThen` \_ -> styleParser (not bolded))
<|> (anyChar
`andThen` \c -> styleParser bolded
`andThen` \cs -> (succeed ((c, style) :: cs)))
示例 "a(!BOLD!)b(!BOLD!)c"
的解析器结果将包含列表 [('a', Unstyled), ( 'b', Bold), ('c', Unstyled)]
,因此我们需要进行一些映射和折叠,以便将其转换为 Html msg
值列表:
htmlParser : Parser (List (Html msg))
htmlParser =
styleParser False
`andThen` (succeed << foldStyledHtml)
foldStyledHtml : List (Char, Style) -> List (Html msg)
foldStyledHtml chars =
let
foldSingleStyledHtml =
List.foldr (\(c, s) (cs, _) -> (c :: cs, s)) ([], Unstyled)
>> \(chars, style) ->
let str = String.fromList chars
in case style of
Unstyled -> text str
Bold -> b [] [ text str ]
in
groupWhile (\a b -> snd a == snd b) chars
|> List.map foldSingleStyledHtml
然后您可以使用以下命令输出一些示例文本:
main =
case parse htmlParser testInput of
(Ok htmls, _) -> div [] htmls
(Err err, _) -> div [ style [("color", "red")] ] [ text <| toString <| err]
我已经发布了此 in a gist 的完整源代码。您还需要 elm-community/list-extra
包。希望这有帮助!
关于haskell - ELM/ haskell : use Regular expression(Regex) to search a String and render Html view,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37912233/
我是一名优秀的程序员,十分优秀!