schlechtwetterfront / fuzzy-rs Goto Github PK
View Code? Open in Web Editor NEWFuzzy matching algorithm based on Sublime Text's string search.
License: Apache License 2.0
Fuzzy matching algorithm based on Sublime Text's string search.
License: Apache License 2.0
How does the score relate to the number of chars matched?
I'm asking because I want to eliminating unwanted matches.
E.g. let's say the needle
is "reverb"
and the haystack
is "roller"
, then I wouldn't want to accept this as a match, even though they have 3 chars in common. (Or even when haystack
is "render"
with 4 chars in common.)
Should I just increase the bonus_consecutive
? Is that for consecutive chars or words? And is penalty_distance
the penalty for distance between consecutive streaks of chars?
What is the difference between using a higher bonus_consecutive
and a lower penalty_distance
?
And which threshold should I use to eliminate the bad matches if they get a low score (because as soon as they have 1 char in common, they will get Some(score), right)?
Which values for both bonuses should I use so that only if a word in needle
also occurs as a consecutive group in haystack
will it constitute a match? Would it be possible to NOT eliminate the whitespace in needle
so that matched groups can get higher scores (proportional to group length))?
I want to find the most likely file that is meant by a user entering the file name.
Can I just compare the scores returned by best_match
(and use the highest one) or are they not comparable across different target strings (same pattern string)?
If I want case insensitive matching, do I have to lowercase both the pattern and target strings? Or only the pattern string?
When the pattern is "release" and tested against the targets "release" and "a.release", it will give both the same score (448), but it would be better to give a higher score for a pattern that covers more chars of the target.
In this case, all of the pattern's chars are found in "release", so the coverage is 1.0, but the coverage of "a.release" is only 7/9=0.777.
Now this coverage ratio can be multiplied with some other factor in the score formula (maybe not necessarily multiplied with the final score), to ensure that fuller (and thus more specific) matches get higher scores.
Not sure if this idea is too simple but I think it should work.
The use case where this came up is:
I'm using this code to match against FX parameters:
(param_i, _param, _) =<< plugin.params.iter().enumerate().filter_map(|(i, param)|
best_match2(&find_param.param, ¶m.to_lowercase()).map(|score| (i, param, score))
).max_by_key(|&(_, _, score)| score);
And there is an FX plugin that has these two parameter names, so when I meant to find the param named "release", it found "a.release" instead because both got the same score :(
(And for max_by_key
: If several elements are equally maximum, the last element is returned.
)
Maybe there are better ways to give them different scores so that it would find the intended one, but the above coverage ratio was the first idea that came to mind..
As long as this issue exists, there is no way for me to write the pattern differently in my config file so that it will find the intended param, because it already is as specific as it can be.
Not quite sure how to put it on title but the example will be quite clear I hope:
This works, I get a match:
let s = "some search thing";
let search = "some search";
let result = best_match(search, s);
assert!(result.is_some());
But this does not match, returns None
:
let s = "some search thing";
let search = "search some";
let result = best_match(search, s);
assert!(!result.is_some());
Is this intended behavior?
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\lib
core\option.rs:355:21
stack backtrace:
0: std::sys::windows::backtrace::set_frames
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\sys\
windows\backtrace\mod.rs:104
1: std::sys::windows::backtrace::set_frames
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\sys\
windows\backtrace\mod.rs:104
2: std::sys::windows::backtrace::set_frames
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\sys\
windows\backtrace\mod.rs:104
3: std::sys_common::backtrace::print
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\sys_
common\backtrace.rs:59
4: std::sys_common::backtrace::print
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\sys_
common\backtrace.rs:59
5: std::panicking::default_hook
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\pani
cking.rs:227
6: std::panicking::rust_panic_with_hook
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\pani
cking.rs:476
7: std::panicking::continue_panic_fmt
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\pani
cking.rs:390
8: std::panicking::rust_begin_panic
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\pani
cking.rs:325
9: core::panicking::panic_fmt
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libcore\pan
icking.rs:77
10: core::panicking::panic
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libcore\pan
icking.rs:52
11: sublime_fuzzy::FuzzySearch::score_deep
12: sublime_fuzzy::FuzzySearch::score_deep
13: sublime_fuzzy::FuzzySearch::score_deep
14: sublime_fuzzy::FuzzySearch::score_deep
15: sublime_fuzzy::FuzzySearch::score_deep
16: sublime_fuzzy::FuzzySearch::score_deep
17: sublime_fuzzy::FuzzySearch::score_deep
18: sublime_fuzzy::FuzzySearch::score_deep
19: sublime_fuzzy::FuzzySearch::best_match
20: sublime_fuzzy::best_match
21: <isize as core::iter::traits::Sum>::sum
22: <core::iter::Map<I, F> as core::iter::iterator::Iterator>::fold
23: <core::iter::Map<I, F> as core::iter::iterator::Iterator>::fold
24: pipeline::Paragraph::bake
25: <T as core::any::Any>::get_type_id
26: std::rt::lang_start_internal::{{closure}}
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\rt.r
s:59
27: std::rt::lang_start_internal::{{closure}}
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\rt.r
s:59
28: panic_unwind::__rust_maybe_catch_panic
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libpanic_un
wind\lib.rs:102
29: std::panicking::try
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\pani
cking.rs:289
30: std::panicking::try
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\pani
cking.rs:289
31: std::panicking::try
at /rustc/6bfb46e4ac9a2704f06de1a2ff7a4612cd70c8cb\/src\libstd\pani
cking.rs:289
32: main
33: invoke_main
at f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:64
34: invoke_main
at f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:64
35: BaseThreadInitThunk
36: RtlUserThreadStart
:(
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.