本文介绍了ELM / Haskell:使用正则表达式(正则表达式)搜索字符串并呈现Html视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我想要做的是使用正则表达式解析 string ,并获取 Html 元素作为输出,以便函数签名应如下所示: b $ b parse:String - > Html Msg 在我们潜入代码之前,让我们举一个例子来说明代码应该如何运作有一个清晰的想法,给出如下的字符串: 输入:hello(!BOLD!)我是一个粗体文本(! BOLD!)bla bla la 期望输出:div [] [texthello,b [] [textI am a bold为了达到这个目的,我使用了ELM软件包中提供的正则表达式库。 $ b replace:HowMany - >正则表达式 - > (匹配 - >字符串) - >字符串 - >字符串 在上面的函数之上,我创建了这里列出的2个函数: $ b $ pre $ myReplace str表达式= 替换(全部)(正则表达式)matchToString str --myreplacehello(!BOLD !)bold(!BOLD!)(!BOLD!)==hello b [] [] hello $ 带有下面的帮助函数,这个函数接受一个匹配并指定正则表达式的开始和结束。 c> matchToString:Match - > String matchToString match = case match.number`rem` 2 of 0 - >] - mtaches闭括号 _ - > B [] [ - 附加开括号 但我想要的是: div [] [texthello,b [] [textbold]] 我的代码并编写完整的解析器?或者我怎么能在哈斯克尔实现相同的目的? 参考: elm正则表达式源代码 解决方案正则表达式开始在这种情况下失去权力并变得过于复杂。相反,我建议您查看解析器组合器,它更加强大,同时易于维护和推理。 在这个例子中,我将使用 Bogdanp / elm-combine 包。 这里我们将构建一个解析器,直到它遇到(!BOLD!)并且将保持为粗体直到它找到另一个(!BOLD!)条目。输出将是字符元组的列表,并且它们是否是 Unstyled 或 Bold 。 警告:可能有更简洁的组合器来实现这一点,但我对于艺术相对来说比较陌生 导入Html.Attributes公开(..)导入组合公开(..) ..导入Combine.Char公开(..)导入Combine.Infix公开(..)导入字符串导入List.Extra公开(groupWhile) 类型风格 =未风格 |粗体 styleParser:Bool - >解析器(List(Char,Style)) styleParser加粗= 让 style =如果加粗然后粗体else unstyled 在(end`and Then` always []))< |> (字符串(!BOLD!)`和Then` \_> styleParser(不加粗))< |> ((c,style):: cs)))`和then` \c-& code> 解析器对于例子a(!BOLD!)b(!BOLD!)的结果c将包含列表 [('a',Unstyled),('b',Bold),('c',Unstyled)] ,所以我们需要做一些映射和折叠,以便将其转换为 Html msg 值的列表: htmlParser:Parser(List(Html msg)) htmlParser = styleParser False `andThen` ;< 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字符风格为 Unstyled - >文本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] 我已经发布了这个的要点。您还需要包 elm-community / list-extra 。希望这有助于! what I am trying to do is to parse string using regular expression and get Html element as output so the function signature should be as following:parse : String -> Html Msgbefore we dive in the code let us take an example how the code should behave in order to have a clear idea, given a the below string as below :input : hello (!BOLD!) I Am a bold text (!BOLD!)bla bla laexpected output : div [ ][ text "hello", b [ ][ text "I Am a bold text" ] , text "bla la la"] ]in order to achieve this goal, I have used the regex library provided in ELM packagereplace : HowMany -> Regex -> (Match -> String) -> String -> Stringon top of the above function, i created the 2 function listed here after :myReplace str expression = replace (All) ( regex expression ) matchToString str --myreplace "hello (!BOLD!) bold (!BOLD!) " "(!BOLD!)" == "hello b[][] hello" with the below helper function, this function take a Match and specify the start and the end for the regular expressionmatchToString : Match -> StringmatchToString match = case match.number `rem` 2 of 0 ->"]" -- mtaches the close bracket _ -> "B [][" --mtaches the open bracketbut what I want to get is : div [][text "hello", b[][text "bold"]]how could I improve my code and write the full parser? or how could I achieve the same purpose in haskell?reference : elm regex source 解决方案 Regular Expressions start to lose their power and become overly complex in cases like this. Instead, I recommend looking into Parser Combinators which are much more powerful while being easier to maintain and reason about.For this example I'll be using the Bogdanp/elm-combine package.Here we'll build up a parser that takes a string and assumes it's unstyled until it hits (!BOLD!) and will remain bold until it finds another (!BOLD!) entry. The output will be a list of tuples of characters and whether they are Unstyled or Bold. caveat: there are probably more concise combinators to achieve this but I'm relatively new to the artimport Html exposing (..)import Html.Attributes exposing (..)import Combine exposing (..)import Combine.Char exposing (..)import Combine.Infix exposing (..)import Stringimport List.Extra exposing (groupWhile)type Style = Unstyled | BoldstyleParser : 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)))The result of that parser for the example "a(!BOLD!)b(!BOLD!)c" would contain the list [('a', Unstyled), ('b', Bold), ('c', Unstyled)], so we need to do some mapping and folding in order to turn that into a list of Html msg values: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 foldSingleStyledHtmlYou can then output some example text using the following:main = case parse htmlParser testInput of (Ok htmls, _) -> div [] htmls (Err err, _) -> div [ style [("color", "red")] ] [ text <| toString <| err]I've posted the full source of this in a gist. You'll also need the package elm-community/list-extra. Hope this helps! 这篇关于ELM / Haskell:使用正则表达式(正则表达式)搜索字符串并呈现Html视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-18 13:37