Find names of people and places with OneNLP’s packaged English model.
dotnet add package RecursiveAI.OneNlp dotnet add package RecursiveAI.OneNlp.Models.English
Requires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.
using RecursiveAI.OneNlp; var entities = Nlp.Entities( "Angela Merkel visited Paris."); foreach (var entity in entities) Console.WriteLine( $"{entity.Text}: {entity.Label}");
The snippet prints each detected name and its label.
Angela Merkel: PER Paris: LOC
PER means person, LOC location, ORG organization and MISC miscellaneous (where the model’s training data includes that label).
Unzip the example, then dotnet run.
The full program
The download’s Program.cs uses the same visible input as the snippet at the top. No input files are needed.
The download’s Program.cs is the snippet above.
dotnet run prints:
Angela Merkel: PER Paris: LOC
If the required language model is missing, ModelNotAvailableException names the package to add; nothing is downloaded.
Variations
Keep character offsets. The explicit language overload skips language detection; offsets locate the names in the original string. This is a standalone replacement for Program.cs.
using RecursiveAI.OneNlp; var entities = Nlp.Entities("Angela Merkel visited Paris.", Language.English); foreach (var entity in entities) Console.WriteLine($"{entity.StartChar}..{entity.EndChar}: {entity.Text}");
0..13: Angela Merkel 22..27: Paris
Related recipes
- Detect the language of text in C#
- Tokenize text in C#
- Split text into sentences in C#
- Lemmatize text in C#
The short answer
Add the core package and RecursiveAI.OneNlp.Models.English, then call Nlp.Entities(text). Each returned span has its text, label and character offsets. In the example, Angela Merkel is labeled PER and Paris is labeled LOC. The English model runs locally; it comes with its NuGet package rather than being downloaded on first use.
How do I use named entity recognition in C#?
Use the complete program above as a starting point. Its input is an ordinary sentence, not a pretokenized array. The model package documentation explains how a package registers a pipeline for the high-level API. Adding the English package is sufficient; the application does not need to load a separate weights file.
The result is a list of spans in text order without overlaps. Text is the original substring, not a canonical name or database identifier. A span recognizing “Paris” does not tell you which municipality is intended, and recognizing a person does not resolve that person to a contact record. Keep those application decisions separate from extraction.
The variation prints StartChar and EndChar. The end is exclusive, so the name occupies the range from the start up to, but not including, the end. Use character offsets when highlighting names in the original string; Start and End instead address tokens. Preserve the string unchanged while consuming those offsets. Normalizing or editing it afterward can invalidate the positions.
The high-level API can detect the input language. When the language is already known, the explicit Language.English overload avoids that choice. This matters for short names or brief messages where the text contains little language evidence. The explicit overload still needs the corresponding model package.
What is a named entity recognition model?
It is the trained component that predicts which token sequences are names and assigns their types. OneNLP’s fast-tier documentation describes the pipeline’s EntityRecognizer and the entity labels from its training data: PER, ORG, LOC, and MISC where the data contains it. A model does not necessarily find every name, and different text domains can produce different mistakes. Check representative sentences from your own data, including ambiguous names and sentences with no entities.
A missing language model is not the same as an empty result. An empty list means the model returned no entities. A missing package raises ModelNotAvailableException, with a message naming what to add. By contrast, Nlp.Analyze can return tokens and sentence boundaries without model annotations when a language package is absent; don’t interpret that fallback as successful entity extraction.
For custom types, the library documents a separate open-type entity path and its required multilingual model. It isn’t enabled by adding a new label to this English example. Choose the model and API for the types you need, and keep its deployment requirements separate from this small person/place example.