hello folks, I have a meander puzzle I'm trying to solve and hope you can me figure it 🙂 this is what I have now:
(m/search
[1
2
true
3
"foo"
"bar"
4
5
"not after thing"
6
true
34
"more"
"text"
"thing"
4
5]
[_ ... true _ . (m/pred string? !n) ... . _ ...]
!n)https://clojurians.slack.com/archives/CFFTD7R6Z/p1651790046071399
@jimmy 😅 ?
so, what I'm trying to extract here are the strings, that occur after a true entry and skipping the item right after it
current result:
=> ([] ["foo"] ["foo" "bar"] [] ["more"] ["more" "text"] ["more" "text" "thing"])
the string "not after thing" should not match because it doesn't fits in the true + any criteria
my target goal here is to have:
=> (["foo" "bar"] ["more" "text" "thing"])
how would you guys go about this case?
Isn’t search supposed to find multiple instances of the given pattern? Try find?
but I want multiple instances of the thing
the pattern happens multiple times in the sequence, and I want all of them
ah
Why do you have string? !n) ... . _ ...] when you only want to drop the item after true if I understand correctly?
I want to drop 1 line after the true, and get all the items that are strings after that, a non-string should stop the capture of that group
but a non string won’t match pred string? what’s the . _ for after the pred?
my real case is some text processing that I'm doing (from PDF's, which are very messy :P), so I'm looking for a start condition to find something (the true is an example here), then I have to skip some lines, start grabbing all the items that match a condition in sequence, stop, and look for that pattern down again, makes sense?
Uhg PDFs … <ptsd dog gif/>
. _ after the pred is to allow for extra items after, the . partitions it, and _ ... allow for other things after my match
Just wondering because your current results look “exploded”
yeah, I dont fully understand what I'm doing, but this is the best aproximation of what I need that I could figure 😛
removing the . _ .... results in nothing matching
> The . operator, read as “partition”, partitions the collection into two parts: left and right. This operator is used primarily to delimit the start of a variable length subsequence. It is important to note that both ... and ..n act as partition operators as well.
Do you even need ... ?
(I’m a noob)
..1 should probably filter out the empty matches
which of the ...?
..1 means 1 repetition
(so its same as not using it at all :P)
Docs say at least 1
ah, yeah, zero could match too
you can play with my example if you like to try a bit, but in my tests here, removing any of hte things breaks the match
if you put ..1 after string pred does it keep the empty matches still?
I need to get my hands on a repl again 😛
..1 there would match at max 1 item, and I want many there
..1 = 1 or more things
if not, https://github.com/noprompt/meander/blob/epsilon/doc/operator-overview.md#subsequences need a PR
ah, you right, yeha, that's better, it removes the empty cases
(m/search
[1
2
true
3
"foo"
"bar"
4
5
"not after thing"
6
true
34
"more"
"text"
"thing"
4
5]
[_ ... true _ . (m/pred string? !n) ..1 . _ ...]
!n)
=> (["foo"] ["foo" "bar"] ["more"] ["more" "text"] ["more" "text" "thing"])this is my though process on the current matcher:
[_ ... ; allow for precedent items
true _ . ; find my starting point
(m/pred string? !n) ..1 . ; matches every string in sequence
_ ... ; allow for successor items
]Ok now we just need to make !n greedy I guess?
yeah, I also wonder if there is a completly different solution that I'm just not aware of (some operator on meander that may be able to handle it)
Did you play around with scan?
yeah, but scan is for more regular things on a sequence afaik
this works, but its quite ugly XD
(->> (m/search
[1
true
3
"a"
true
3
"b"
2
true
3
"foo"
"bar"
4
5
"not after thing"
6
true
34
"more"
"text"
"thing"
4
5]
[_ ... true _ . (m/pred string? !n) ..1 . _ ...]
!n)
(partition-all 2 1)
(filter #(or (nil? (second %))
(>= (count (first %))
(count (second %)))))
(map first))
=> (["a"] ["b"] ["foo" "bar"] ["more" "text" "thing"])What would this do: (m/pred string? !n ..1)
moving the ..1 inside m/pred?
I think that's not valid syntax
pred can take multiple patterns and they all must match the predicate
No method in multimethod 'compile-specialized-matrix' for dispatch value: :dt+wew
maybe not with ... then 😄
This is close
(m/search
[1
2
true
3
"foo"
"bar"
4
5
"not after thing"
6
true
34
"more"
"text"
"thing"
4
5]
[_ ... true _ (m/pred string? !s) . (m/pred string? !s) ... _ ...] !s
)
The problem is getting all intermeadiate states
(["foo"] ["foo" "bar"] ["more"] ["more" "text"] ["more" "text" "thing"])
@ben.sless we got the same by replace the original ... after the pred with ..1
I got this far:
=> (m/search input [_ ... true _ (m/pred string? !n) ..1 . _ ...] !n)
(["foo"] ["more"])This match finds only the more next thing
[_ ... true _ (m/pred string? !s) . (m/pred string? !s) ... (m/pred (complement string?)) _ ...] !sSlightly more concise
[_ ... true _ . (m/pred string? !s) ... (m/pred (complement string?)) _ ...] !s
still wrongGOT IT
(m/search
[1 2 true 3 "foo" "bar" 4 5 "not after thing" 6 true 34 "more" "text" "thing" 4 5]
[_ ... true _ . (m/pred string? !s) ... (m/pred (complement string?)) . _ ...] !s
)nice!
I think we can extract this pattern somehow in a syntax thing, to avoid writing the pred + complement pred
looking at this: https://github.com/noprompt/meander/blob/epsilon/doc/cookbook.md#reuse-subpatterns-in-other-patterns
humm, but now not sure if that works, it needs to splice the thing
May not need the complement
Important part was judicious use of dot, which is a stop point for the regex pattern looking left
problem is without it you get more than one success
What is this for?
@ben.sless there is a problem also when the matching is at the end of the collection, in this example it fails to get the correct results:
(m/search
[1 2 true 3 "foo" "bar" 4 5 "not after thing" 6 true 34 "more" "text" "thing"]
[_ ... true _ . (m/pred string? !s) ... . (m/pred (complement string?)) . _ ...] !s
)Fun! Try to add another pattern where the vector ends before the complement
Basically this but how to DRY it?
(m/search
[1 2 true 3 "foo" "bar" 4 5 "not after thing" 6 true 34 "more" "text" "thing"]
[_ ... true _ . (m/pred string? !s) ..1] !s
[_ ... true _ . (m/pred string? !s) ..1 (m/pred (complement string?)) . _ ...] !s)
=>
(["foo" "bar"] ["more" "text" "thing"])Can’t seem to splice ~@ patterns defined with m/with
Seems like the regex $ (end) operator is missing