ELM / Haskell:使用正则表达式(正则表达式)搜索字符串并呈现Html视图 [英] ELM/Haskell : use Regular expression(Regex) to search a String and render Html view

查看:214
本文介绍了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 $ b $ p 

带有下面的帮助函数,这个函数接受一个匹配并指定正则表达式的开始和结束。 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 值的列表:

< pre-class =lang-elm prettyprint-override> 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 Msg

before 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 la

expected 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 package

replace : HowMany -> Regex -> (Match -> String) -> String -> String

on 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 expression

matchToString : Match -> String
matchToString match =
  case  match.number `rem` 2  of
    0 ->"]" -- mtaches the close bracket
    _ -> "B [][" --mtaches the open bracket

but 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 art

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)))

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 foldSingleStyledHtml

You 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视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆