ktsu.FuzzySearch 1.3.12

Prefix Reserved
dotnet add package ktsu.FuzzySearch --version 1.3.12
                    
NuGet\Install-Package ktsu.FuzzySearch -Version 1.3.12
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ktsu.FuzzySearch" Version="1.3.12" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ktsu.FuzzySearch" Version="1.3.12" />
                    
Directory.Packages.props
<PackageReference Include="ktsu.FuzzySearch" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ktsu.FuzzySearch --version 1.3.12
                    
#r "nuget: ktsu.FuzzySearch, 1.3.12"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ktsu.FuzzySearch@1.3.12
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ktsu.FuzzySearch&version=1.3.12
                    
Install as a Cake Addin
#tool nuget:?package=ktsu.FuzzySearch&version=1.3.12
                    
Install as a Cake Tool

ktsu.FuzzySearch

A lightweight .NET library that provides fuzzy string matching capabilities, allowing for approximate string matching with intelligent scoring.

License NuGet Version NuGet Version NuGet Downloads GitHub commit activity GitHub contributors GitHub Actions Workflow Status

Introduction

FuzzySearch is a .NET library that provides fuzzy string matching capabilities with intelligent scoring. It's perfect for implementing search-as-you-type features, command palettes, or any application requiring flexible string matching.

The whole library is one static class, Fuzzy, with two Contains overloads: one that answers whether a subject matches a pattern, and one that also hands back a score you can rank by.

Features

  • Subsequence Matching: Match a subject against a pattern whose characters appear in order but not necessarily together
  • Intelligent Scoring: Rank matches by quality with a scoring algorithm that rewards adjacent matches, matches after separators, and matches at camelCase boundaries
  • Case Insensitive: Matching always ignores case; there is no case-sensitive mode
  • Unicode Aware: Input is normalized to NFC and compared one codepoint at a time, so surrogate pairs match as a whole
  • Span Based: Takes ReadOnlySpan<char>, and allocates nothing for ASCII input
  • Lightweight: Minimal dependencies, focused on performance
  • Well-tested: Comprehensive test suite ensuring reliability

Installation

Package Manager Console

Install-Package ktsu.FuzzySearch

.NET CLI

dotnet add package ktsu.FuzzySearch

Package Reference

<PackageReference Include="ktsu.FuzzySearch" Version="x.y.z" />

Usage Examples

Basic Matching

The simplest way to check if a string contains characters from a pattern in sequence:

using ktsu.FuzzySearch;

class Program
{
    static void Main()
    {
        string text = "Hello World";
        string pattern = "hlo";
        
        bool isMatch = Fuzzy.Contains(text, pattern); // Returns true
    }
}

Matching with Scoring

The second overload also reports a score, so you can tell a good match from a barely-there one:

using ktsu.FuzzySearch;

class Program
{
    static void Main()
    {
        string text = "Hello World";
        string pattern = "hlo";

        bool isMatch = Fuzzy.Contains(text, pattern, out int score);

        Console.WriteLine($"Is match: {isMatch}"); // True
        Console.WriteLine($"Score: {score}");      // Higher is better
    }
}

The score is an unbounded int, not a normalized ratio. It is only meaningful when comparing candidates against the same pattern, and it is reported whether or not the whole pattern was found — a near miss still scores. Use the return value to decide whether it matched at all, and the score to order the matches.

Ranking a Collection

There is no built-in filter method. Ranking a collection is a Contains call per candidate:

using ktsu.FuzzySearch;

class Program
{
    static void Main()
    {
        string[] items =
        [
            "AppDataStorage",
            "Application Settings",
            "Data Store",
            "File System",
            "Storage Provider",
        ];

        string pattern = "stor";

        List<(string Item, int Score)> matches = [];
        foreach (string item in items)
        {
            if (Fuzzy.Contains(item, pattern, out int score))
            {
                matches.Add((item, score));
            }
        }

        foreach ((string item, int score) in matches.OrderByDescending(match => match.Score))
        {
            Console.WriteLine($"{item} (Score: {score})");
        }

        // Storage Provider (Score: 15)
        // Data Store (Score: 14)
        // AppDataStorage (Score: 10)
    }
}

Matching Against Objects

The same shape works for objects — project each one to the text you want matched:

using ktsu.FuzzySearch;

class Program
{
    sealed class FileItem
    {
        public required string Name { get; init; }
        public required string Path { get; init; }
    }

    static void Main()
    {
        FileItem[] files =
        [
            new() { Name = "Document.pdf", Path = "/documents/" },
            new() { Name = "Presentation.pptx", Path = "/presentations/" },
            new() { Name = "Spreadsheet.xlsx", Path = "/spreadsheets/" },
        ];

        string pattern = "doc";

        foreach (FileItem file in files)
        {
            if (Fuzzy.Contains(file.Name, pattern, out int score))
            {
                Console.WriteLine($"{file.Name} (Score: {score})");
            }
        }
    }
}

API Reference

Fuzzy Static Class

Fuzzy is the library's entire public surface. It is a static class with two methods, both overloads of Contains.

Methods
Name Parameters Return Type Description
Contains ReadOnlySpan<char> subject, ReadOnlySpan<char> pattern bool Whether subject contains every character of pattern, in order
Contains ReadOnlySpan<char> subject, ReadOnlySpan<char> pattern, out int outScore bool The same answer, plus a match-quality score

Both overloads take ReadOnlySpan<char>, so a string argument is passed straight through by the compiler's implicit conversion — there is no separate string overload to look for.

Behaviour
  • Case is always ignored. There is no option to make matching case-sensitive.
  • An empty pattern matches any non-empty subject, and scores 0. An empty subject never matches.
  • Scores are unbounded ints, comparable only within a single pattern. outScore is set even when the method returns false.
  • Input is normalized to NFC before comparison, so precomposed and decomposed text match. This relies on the runtime's globalization data: under InvariantGlobalization, string.Normalize is a no-op and the two forms will not match.
  • Comparison advances one codepoint at a time, so a surrogate pair matches only as a whole and a lone surrogate cannot match half of an unrelated character.
Scoring
Rule Effect
Match adjacent to the previous match +5
Match after a _ or space separator +10
Match at a camelCase boundary +10
Each unmatched character -1
Unmatched characters before the first match -1 each, capped at -5

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please make sure to update tests as appropriate and adhere to the existing coding style.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on ktsu.FuzzySearch:

Package Downloads
ktsu.TextFilter

A library providing methods for matching and filtering text. It supports glob patterns, regular expressions, and fuzzy matching.

ktsu.ImGuiWidgets

A library of custom widgets using ImGui.NET and utilities to enhance ImGui-based applications.

ktsu.Frontmatter

A .NET library for processing and manipulating YAML frontmatter in markdown files.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.12 82 9/24/2026
1.3.11 162 9/23/2026
1.3.10 293 9/22/2026
1.3.9 541 9/22/2026
1.3.8 115 9/21/2026
1.3.7 629 9/18/2026
1.3.6 528 9/17/2026
1.3.5 630 9/17/2026
1.3.4 113 9/16/2026
1.3.3 422 9/16/2026
1.3.2 618 9/14/2026
1.3.1 792 9/14/2026
1.3.0 210 9/13/2026
1.2.40 119 9/11/2026
1.2.39 4,414 9/3/2026
1.2.38 1,525 8/26/2026
1.2.37 1,246 8/21/2026
1.2.36 488 8/20/2026
1.2.35 684 8/19/2026
1.2.34 160 8/18/2026
Loading failed

## v1.3.12 (patch)

Changes since v1.3.11:

- Bump the ktsu group with 9 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))