DotNet.Glob
2.0.1
See the version list below for details.
dotnet add package DotNet.Glob --version 2.0.1
NuGet\Install-Package DotNet.Glob -Version 2.0.1
<PackageReference Include="DotNet.Glob" Version="2.0.1" />
paket add DotNet.Glob --version 2.0.1
#r "nuget: DotNet.Glob, 2.0.1"
// Install DotNet.Glob as a Cake Addin #addin nuget:?package=DotNet.Glob&version=2.0.1 // Install DotNet.Glob as a Cake Tool #tool nuget:?package=DotNet.Glob&version=2.0.1
DotNet.Glob
A fast (probably the fastest) globbing library for .NET.
Branch | Build Status | NuGet |
---|---|---|
Master | ||
Develop |
This library does not use Regex - I wanted to make something much faster.
The latest benchmarks show that DotNet.Glob signficantly outperforms Regex.
The benchmarks use BenchmarkDotNet and can be located inside this repo. Just dotnet run
them. Some Benchmark results have also been published on the wiki: https://github.com/dazinator/DotNet.Glob/wiki/Benchmarks-(vs-Compiled-Regex)
Usage
- Install the NuGet package.
Install-Package DotNet.Glob
- Add using statement:
using DotNet.Globbing;
- Parse a glob from a pattern
var glob = Glob.Parse("p?th/*a[bcd]b[e-g]a[1-4][!wxyz][!a-c][!1-3].*");
var isMatch = glob.IsMatch("pAth/fooooacbfa2vd4.txt");
Build a glob fluently
You can also use the GlobBuilder
class if you wish to build up a glob using a fluent syntax.
This is also more efficient as it avoids having to parse the glob from a string pattern.
So to build the following glob pattern: /foo?\\*[abc][!1-3].txt
:
var glob = new GlobBuilder()
.PathSeperator()
.Literal("foo")
.AnyCharacter()
.PathSeperator(PathSeperatorKind.BackwardSlash)
.Wildcard()
.OneOf('a', 'b', 'c')
.NumberNotInRange('1', '3')
.Literal(".txt")
.ToGlob();
var isMatch = glob.IsMatch(@"/fooa\\barrra4.txt"); // returns true.
Patterns
The following patterns are supported (from wikipedia):
Wildcard | Description | Example | Matches | Does not match |
---|---|---|---|---|
* | matches any number of any characters including none | Law* | Law, Laws, or Lawyer | |
? | matches any single character | ?at | Cat, cat, Bat or bat | at |
[abc] | matches one character given in the bracket | [CB]at | Cat or Bat | cat or bat |
[a-z] | matches one character from the range given in the bracket | Letter[0-9] | Letter0, Letter1, Letter2 up to Letter9 | Letters, Letter or Letter10 |
[!abc] | matches one character that is not given in the bracket | [!C]at | Bat, bat, or cat | Cat |
[!a-z] | matches one character that is not from the range given in the bracket | Letter[!3-5] | Letter1, Letter2, Letter6 up to Letter9 and Letterx etc. | Letter3, Letter4, Letter5 or Letterxx |
In addition, DotNet Glob also supports:
Wildcard | Description | Example | Matches | Does not match |
---|---|---|---|---|
** |
matches any number of path / directory segments. When used must be the only contents of a segment. | /**/some.* | /foo/bar/bah/some.txt, /some.txt, or /foo/some.txt |
Advanced Usages
Parsing options.
By default, when your glob pattern is parsed, DotNet.Glob
will only allow literals which are valid for path / directory names.
These are:
- Any Letter (A-Z, a-z) or Digit
.
,!
,#
,-
,;
,=
,@
,~
,_
,:
This is optimised for matching against paths / directory strings.
However, introduced in version 1.6.4
, you can override this behaviour so that you can include arbitrary characters in your literals. For example, here is a pattern that matches the literal "Stuff
:
// Overide the default options globally for all matche:
GlobParseOptions.Default.Parsing.AllowInvalidPathCharacters = true;
DotNet.Globbing.Glob.Parse("\"Stuff*").IsMatch("\"Stuff"); // true;
You can also just set these options on a per glob pattern basis:
GlobOptions options = new GlobOptions();
options.Parsing.AllowInvalidPathCharacters = allowInvalidPathCharcters;
DotNet.Globbing.Glob.Parse("\"Stuff*", globParseOptions).IsMatch("\"Stuff"); // true;
Case Sensitivity (Available as of version >= 2.0.0)
By default, evaluation is case-sensitive unless you specify otherwise.
GlobOptions options = new GlobOptions();
options.Evaluation.CaseInsensitive = true;
DotNet.Globbing.Glob.Parse("foo*", globParseOptions).IsMatch("FOo"); // true;
Setting CaseInsensitive has an impact on:
- Letter Ranges. Any letter range (i.e '[A-Z]') will now match both lower or upper case characters.
- Character Lists. Any character list (i.e '[ABC]') will now match both lower or upper case characters.
- Literals. Any literal (i.e 'foo') will now match both lower or upper case characters i.e
FoO
will matchfoO
etc.
Match Generation
Given a glob, you can generate random matches, or non matches, for that glob.
For example, given the glob pattern /f?o/bar/**/*.txt
you could generate matching strings like /foo/bar/ajawd/awdaw/adw-ad.txt
or random non matching strings.
var dotnetGlob = Glob.Parse(pattern);
var generator = new GlobMatchStringGenerator(dotnetGlob.Tokens);
for (int i = 0; i < 10; i++)
{
var testString = generator.GenerateRandomMatch();
var result = dotnetGlob.IsMatch(testString);
// result is always true.
// generate a non match.
testString = generator.GenerateRandomNonMatch();
var result = dotnetGlob.IsMatch(testString);
// result is always false.
}
Product | Versions 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 was computed. 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. |
.NET Core | netcoreapp1.0 was computed. netcoreapp1.1 was computed. netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard1.1 is compatible. netstandard1.2 was computed. netstandard1.3 was computed. netstandard1.4 was computed. netstandard1.5 was computed. netstandard1.6 was computed. netstandard2.0 was computed. netstandard2.1 was computed. |
.NET Framework | net40 is compatible. net403 was computed. net45 is compatible. net451 was computed. net452 was computed. net46 is compatible. 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 | tizen30 was computed. tizen40 was computed. tizen60 was computed. |
Universal Windows Platform | uap was computed. uap10.0 was computed. |
Windows Phone | wpa81 was computed. |
Windows Store | netcore was computed. netcore45 was computed. netcore451 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.0
- No dependencies.
-
.NETFramework 4.5
- No dependencies.
-
.NETFramework 4.6
- No dependencies.
-
.NETStandard 1.1
- NETStandard.Library (>= 1.6.1)
NuGet packages (40)
Showing the top 5 NuGet packages that depend on DotNet.Glob:
Package | Downloads |
---|---|
Dazinator.Extensions.FileProviders
Dazinator.Extensions.FileProviders |
|
Casbin.NET
Casbin.NET is a powerful and efficient open-source access control library for .NET (C#) projects. It provides support for enforcing authorization based on various access control models. |
|
Carbon.Feature.Web
Feature to support development and runtime of Web services. |
|
OpenMod.Core
Core service implementations for OpenMod |
|
Traffk.StorageProviders.Common
Common set of functionality, base classes, and add-ons for Traffk.StorageProvider.Interfaces |
GitHub repositories (22)
Showing the top 5 popular GitHub repositories that depend on DotNet.Glob:
Repository | Stars |
---|---|
jellyfin/jellyfin
The Free Software Media System
|
|
Kareadita/Kavita
Kavita is a fast, feature rich, cross platform reading server. Built with the goal of being a full solution for all your reading needs. Setup your own server and share your reading collection with your friends and family.
|
|
rnwood/smtp4dev
smtp4dev - the fake smtp email server for development and testing
|
|
microsoft/kiota
OpenAPI based HTTP Client code generator
|
|
stryker-mutator/stryker-net
Mutation testing for .NET core and .NET framework!
|
Version | Downloads | Last updated |
---|---|---|
3.2.0-alpha.36 | 22,051 | 9/27/2021 |
3.2.0-alpha.33 | 259 | 3/5/2021 |
3.2.0-alpha.32 | 205 | 3/5/2021 |
3.2.0-alpha.31 | 202 | 3/5/2021 |
3.2.0-alpha.30 | 219 | 3/5/2021 |
3.2.0-alpha.29 | 306 | 12/26/2020 |
3.2.0-alpha.26 | 266 | 12/26/2020 |
3.2.0-alpha.25 | 269 | 12/26/2020 |
3.2.0-alpha.22 | 295 | 11/27/2020 |
3.2.0-alpha.21 | 1,181 | 8/21/2020 |
3.1.3 | 1,849,369 | 9/27/2021 |
3.1.2 | 421,708 | 12/26/2020 |
3.1.0 | 6,065,923 | 8/21/2020 |
3.1.0-issue-75.1 | 356 | 5/24/2020 |
3.1.0-alpha0009 | 69,714 | 8/3/2019 |
3.1.0-alpha0004 | 3,375 | 3/24/2019 |
3.1.0-alpha.51 | 293 | 8/21/2020 |
3.1.0-alpha.49 | 313 | 5/24/2020 |
3.1.0-alpha.47 | 309 | 3/5/2020 |
3.0.9 | 212,570 | 3/5/2020 |
3.0.9-beta.1 | 299 | 3/5/2020 |
3.0.8-beta0001 | 1,085 | 2/22/2020 |
3.0.5 | 257,371 | 4/2/2019 |
3.0.2-beta0001 | 1,360 | 4/2/2019 |
3.0.1 | 37,388 | 3/24/2019 |
3.0.1-beta0001 | 1,288 | 3/24/2019 |
3.0.0-alpha0052 | 1,334 | 3/24/2019 |
3.0.0-alpha0048 | 1,330 | 3/24/2019 |
3.0.0-alpha0045 | 1,420 | 2/11/2019 |
3.0.0-alpha0043 | 1,654 | 12/15/2018 |
3.0.0-alpha0041 | 2,754 | 9/12/2018 |
2.2.0-alpha0002 | 1,527 | 9/11/2018 |
2.2.0-alpha0001 | 1,527 | 8/24/2018 |
2.1.4 | 3,927 | 4/2/2019 |
2.1.3 | 1,779 | 3/24/2019 |
2.1.3-beta0001 | 1,415 | 3/24/2019 |
2.1.1 | 263,574 | 9/12/2018 |
2.1.0 | 3,809 | 8/24/2018 |
2.1.0-escaping0001 | 1,588 | 8/15/2018 |
2.1.0-alpha0034 | 1,556 | 8/24/2018 |
2.1.0-alpha0033 | 1,555 | 8/24/2018 |
2.1.0-alpha0022 | 1,680 | 8/10/2018 |
2.1.0-alpha0020 | 1,885 | 4/27/2018 |
2.0.3 | 126,163 | 4/27/2018 |
2.0.3-beta0001 | 2,065 | 4/27/2018 |
2.0.2 | 1,677 | 4/27/2018 |
2.0.1 | 100,883 | 3/27/2018 |
2.0.0 | 7,673 | 3/20/2018 |
2.0.0-alpha0139 | 1,446 | 3/11/2018 |
2.0.0-alpha0137 | 1,479 | 3/11/2018 |
2.0.0-alpha0130 | 1,460 | 3/11/2018 |
2.0.0-alpha0128 | 1,439 | 3/11/2018 |
2.0.0-alpha0127 | 1,472 | 3/11/2018 |
2.0.0-alpha0126 | 1,422 | 3/11/2018 |
2.0.0-alpha0125 | 1,415 | 3/11/2018 |
2.0.0-alpha0124 | 1,424 | 3/11/2018 |
2.0.0-alpha0123 | 1,441 | 3/11/2018 |
2.0.0-alpha0122 | 1,450 | 3/11/2018 |
2.0.0-alpha0121 | 1,406 | 3/11/2018 |
2.0.0-alpha0116 | 1,715 | 12/22/2017 |
2.0.0-alpha0115 | 1,437 | 12/22/2017 |
1.7.0-unstable0022 | 1,602 | 9/6/2017 |
1.7.0-unstable0018 | 1,366 | 8/27/2017 |
1.7.0-unstable0017 | 1,374 | 8/27/2017 |
1.7.0-unstable0013 | 1,376 | 7/12/2017 |
1.7.0-unstable0012 | 1,362 | 7/12/2017 |
1.7.0-unstable0009 | 1,463 | 6/30/2017 |
1.7.0-unstable0004 | 1,387 | 6/6/2017 |
1.7.0-unstable0001 | 1,414 | 5/18/2017 |
1.7.0-alpha0033 | 1,512 | 10/2/2017 |
1.6.9 | 9,783 | 10/2/2017 |
1.6.6 | 2,119 | 9/6/2017 |
1.6.5 | 1,772 | 8/27/2017 |
1.6.4 | 91,430 | 7/12/2017 |
1.6.3 | 1,740 | 6/30/2017 |
1.6.1 | 1,665 | 6/6/2017 |
1.6.0 | 3,133 | 5/18/2017 |
1.6.0-unstable0003 | 1,370 | 5/18/2017 |
1.6.0-unstable0002 | 1,382 | 5/12/2017 |
1.6.0-unstable0001 | 1,610 | 5/5/2017 |
1.5.0 | 1,592 | 5/5/2017 |
1.5.0-unstable0028 | 1,368 | 5/5/2017 |
1.5.0-unstable0027 | 1,417 | 5/5/2017 |
1.5.0-unstable0014 | 1,370 | 3/6/2017 |
1.5.0-unstable0013 | 1,362 | 3/6/2017 |
1.5.0-unstable0011 | 1,469 | 1/7/2017 |
1.5.0-unstable0010 | 1,418 | 1/5/2017 |
1.5.0-unstable0007 | 1,439 | 1/5/2017 |
1.5.0-unstable0006 | 1,469 | 12/19/2016 |
1.5.0-unstable0005 | 1,374 | 12/17/2016 |
1.5.0-unstable0001 | 1,425 | 12/15/2016 |
1.4.2 | 12,766 | 1/5/2017 |
1.4.1 | 10,351 | 12/17/2016 |
1.4.0 | 1,590 | 12/15/2016 |
1.4.0-unstable0004 | 1,439 | 12/15/2016 |
1.4.0-unstable0002 | 1,365 | 12/15/2016 |
1.4.0-unstable0001 | 1,445 | 12/14/2016 |
1.3.0 | 1,607 | 12/14/2016 |
1.3.0-unstable0021 | 1,378 | 12/12/2016 |
1.3.0-unstable0019 | 1,447 | 12/12/2016 |
1.3.0-unstable0018 | 1,439 | 12/12/2016 |
1.3.0-unstable0017 | 1,407 | 12/11/2016 |
1.3.0-unstable0016 | 1,440 | 12/11/2016 |
1.3.0-unstable0015 | 1,467 | 12/11/2016 |
1.3.0-unstable0014 | 1,477 | 12/10/2016 |
1.3.0-unstable0010 | 1,524 | 12/10/2016 |
1.3.0-unstable0008 | 1,470 | 12/10/2016 |
1.3.0-unstable0004 | 1,410 | 12/9/2016 |
1.3.0-unstable0002 | 1,444 | 12/9/2016 |
1.2.2 | 1,664 | 12/10/2016 |
1.2.1 | 1,655 | 12/9/2016 |
1.2.0-unstable0001 | 1,406 | 12/9/2016 |
1.1.0 | 1,748 | 12/9/2016 |
1.1.0-unstable0008 | 1,467 | 12/9/2016 |
1.1.0-unstable0005 | 1,444 | 12/7/2016 |
1.1.0-unstable0002 | 1,341 | 12/7/2016 |
1.1.0-unstable0001 | 1,392 | 12/7/2016 |
1.0.1 | 1,708 | 12/7/2016 |
1.0.0 | 1,649 | 12/7/2016 |
0.1.0 | 2,169 | 12/7/2016 |
0.1.0-unstable0012 | 1,448 | 12/7/2016 |
New features and fixes. See README in Github Repo.