Hello, I'm playing around with meader trying to replicate destructuring, and I can't figure out the correct accumulator syntax This naive rewrite works:
(let [s
(m*/rewrite
[[!b '& ?bs] [!x & ?xs]]
[!b !x
?bs ?xs])]
(s '[[x & xs] [1 2 3]]))
But anything I've tried with accumulators turned out wrong.
Any ideas?Yeah, that fails because you are saying that the repeats for both vectors should be the same. That is what using ?n
twice does. So on that last example, there are 3 elements before the &
and there are only two on the right hand side. So they don’t match.
Well, it's pretty clear they don't match, I just provided some examples of stuff I tired. I'm not sure what would work correctly, though :thinking_face:
Well, it depends on what you want. I’m guessing you want to assign z to nil and xs to nil in that least example? If so, you can do something like this
(let [s
(m*/rewrite
[[!b ..?n '& ?bs] [!x ..?n & ?xs]]
[!b !x ..?n
?bs ?xs]
[[!b ..?n '& ?bs] [!x ...]]
[!b !x ..?n
?bs nil])]
[(s '[[x & xs] [1 2 3]])
(s '[[x y & xs] [1 2 3]])
(s '[[x y z & xs] [1 2 3]])
(s '[[x y z & xs] [1 2]])])
Ah, the second pattern is for when the first doesn't match then it all gets accumulated to !x
?
Yep exactly right.
Sorry meant to reply to this. We haven't focused much on text so I'm not sure if there would be a lot of benefit in using meander for this. Might be possible though.
A couple things. Not 100% sure what you mean by accumulators. I'm also guessing you are using strategies. Any reason? Finally an example of what isn't working would be super helpful for knowing how we can help. Not sure if someone has reimplemented drstructuring already using meander, but should definitely be possible.
Hard to say without looking at what you are doing, but I’d first look at Instaparse and maybe pair it with meander.
Yeah, that is a pretty good combination.
thanks guys, I find instaparse a bit too bulky for what I’m doing, because its not much a syntax, its more like a text email that I’m trying to extract data from. I’ve been doing ok using just meander and regex so far. one trick I did that made my life easier was to pre-parse the text and transform it in a “hiccup like” syntax, where there is one entry for each line. This makes easier to match on specific line numbers (when they make sense) and also avoid dealing with line breaks
(defn text->hiccup [text]
(into []
(map-indexed
#(vector (keyword (str "l" %)) %2))
(-> text
(str/split-lines))))
them I can match like this:
(-> (m/search hiccup
(m/scan [:l0 ?store])
{:riviera-delivery.order/store ?store}
(m/scan [:l2 (m/re #"Pedido número: #(\d+)" [_ ?id])])
{:riviera-delivery.order/id ?id}
(m/scan [_ (m/re #".*Total Geral: R\$(\d+,\d+).*" [_ ?total])])
{:riviera-delivery.order/total (u/parse-br-money ?total)}
(m/scan [_ (m/re #".*(\d+) x \.\.\.\.\.\. (.+?) \.\.\.\.\.\. R\$(\d+,\d+).*" [_ ?q ?n ?p])])
{:riviera-delivery.order/items
[{:riviera-delivery.item/quantity ?q
:riviera-delivery.item/price (u/parse-br-money ?p)
:riviera-delivery.item/name ?n}]})
(->> (apply merge-with into)))
example text that I’m matching against:
Padaria Bella Riviera
Pedido número: #1619127436602
Status: Pedido Entregue
Wilker, você será notificado (a) à cada nova alteração de status.
_______________________________________________________________________________________________________
Produtos:
3 x ...... Pão Francês (1unid) ...... R$1,10
1 x ...... Pão Ciabata (1unid) ...... R$5,50