4 ms·
Turn slashes into .*?(/).*? and leave the rest alone? If you don't want to treat slashes specially and want to allow "ab" to match "aqqqb" then I don't t
by jules 14y ago
Turn slashes into
.*?(/).*?
and leave the rest alone?
If you don't want to treat slashes specially and want to allow "ab" to match "aqqqb" then I don't think you can do it without creating a giant regex. You can go for a modified longest common subsequence algorithm.
Edit: here's how you can do it:
// gives one point for each letter matched
// plus an extra point if the next letter is also a match
let rec scorematch = function
| true::true::r -> 2 + scorematch (true::r)
| true::r -> 1 + scorematch r
| false::r -> scorematch r
| [] -> 0
// find the match with best score
let rec search xs ys =
match (xs,ys) with
| (x::xr, y::yr) ->
let matches = [false::search xr ys; false::search xs yr]
let matches = if x=y then (true::search xr yr)::matches else matches
matches |> List.maxBy scorematch
| _,ys -> List.map (fun _ -> false) ys
let underline xs ys = search (List.ofSeq xs) (List.ofSeq ys)
|> List.map (fun b -> if b then "-" else " ")
|> String.Concat
for x in ["foobarbaz"; "foobaXrbaz"; "foobXaXrbaz"; "foobXaXrbazr"] do
Console.WriteLine x
Console.WriteLine (underline "bar" x)
For search term "bar" this outputs:
foobarbaz
---
foobaXrbaz
-- -
foobXaXrbaz
- - -
foobXaXrbazr
-- -
You'll want to memoize this or apply dynamic programming.
- scottjad 14y agoThank you!