I am trying to search a paragraph for certain text with Regex. I'd like the realist to return X number of words before and after and add highlights around all the occurrences of the text with.
For Example: Consider the following paragraph. The result should have at least 10 characters before and after with no words cut off. The search term is "dog".
The Dog is a pet animal. It is one of the most obedient animals. There are many kinds of dogs in the world. Some of the are very friendly while some of them a dangerous. Dogs are of different color like black, red, white and brown. Some old them have slippery shiny skin and some have rough skin. Dogs are carnivorous animals. They like eating meat. They have four legs, two ears and a tail. Dogs are trained to perform different tasks. They protect us from thieves b) guarding our house. They are loving animals. A dog is called man's best friend. They are used by the police to find hidden things. They are one of the most useful animals in the world. Doggonit!
The result I desire is an array with that looks like the following:
- The Dog is a pet animal
- many kinds of dogs in the world
- dangerous. Dogs are of different
- rough skin. Dogs are carnivorous
- and a tail. Dogs are trained
- animals. A dog is called
- the world. Doggonit!
What I've Got:
I've search around and have found the following regex that has perfectly returned the results as desired but without adding extra formatting. I created several methods to facilitate each functionality:
private List<List<string>> Search(string text, string searchTerm, bool searchEntireWord) {
var result = new List<List<string>>();
var searchTerms = searchTerm.Split(' ');
foreach (var word in searchTerms) {
var searchResults = ExtractParagraph(text, word, sizeOfResult, searchEntireWord);
result.Add(searchResults);
if (searchResults.Count > 0) {
foreach (var searchResult in searchResults) {
Response.Write("<strong>Result:</strong> " + searchResult + "<br>");
}
}
}
return result;
}
private List<string> ExtractParagraph(string text, string searchTerm, sizeOfResult, bool searchEntireWord) {
var result = new List<string>();
searchTerm = searchEntireWord ? @"\b" + searchTerm + @"\b" : searchTerm;
//var expression = @"((^.{0,30}|\w*.{30})\b" + searchTerm + @"\b(.{30}\w*|.{0,30}$))";
var expression = @"((^.{0," + sizeOfResult + @"}|\w*.{" + sizeOfResult + @"})" + searchTerm + @"(.{" + sizeOfResult + @"}\w*|.{0," + sizeOfResult + @"}$))";
var wordMatch = new Regex(expression, RegexOptions.IgnoreCase | RegexOptions.Singleline);
foreach (Match m in wordMatch.Matches(text)) {
result.Add(m.Value);
}
return result;
}
And I can call it like:
var text = "The Dog is a pet animal. It is one of...";
var searchResults = Search(text, "dog", 10);
if (searchResults.Count > 0) {
foreach (var searchResult in searchResults) {
foreach (var result in searchResult) {
Response.Write("<strong>Result:</strong> " + result + "<br>");
}
}
}
I don't know yet the result of, or how to deal with, multiple occurrences of the word within the 10 characters. ie: if a sentence had "A dog is a dog of course!". I guess I can deal with that later.
Tests:
var searchResults = Search(text, "dog", 0, false); // should include only the matched word
var searchResults = Search(text, "dog", 1, false); // should include the matched word and only one word preceding and following the matched word (if any)
var searchResults = Search(text, "dog", 10, false); // should include the matched word and up to 10 characters (but not cutting off words in the middle) preceding and following it (if any)
var searchResults = Search(text, "dog", 50, false); // should include the matched word and up to 50 characters (but not cutting off words in the middle) preceding and following it (if any)
Issues:
The function I created allows the search to find the searchTerm as a whole word only or part of the word.
What I was doing was a simple Replace(word, "<strong>" + word "</strong>") on the results when displaying them. This works great if I was searching for parts of the word. But when searching for whole words, if the result included the searchTerm as part of the word, that part of the word would highlight.
For example: if I was searching for "dog" and the result was: "All dogs go to dog heaven." The highlighting would come out as "All dogs go to dog heaven." But I want "All dogs go to dog heaven."
Question:
The question is how can I get the matched word wrapped with some HTML like <strong> or anything else I'd want?