Reputation: 1317
I am trying to match words that start with a forward slash in C#.
For example /exit
and I have tried using the regex \b(/exit)\b
but for some reason it doesn't match.
Here's a sample code that I am trying out:
static void Main(string[] args)
{
var commands= new List<string>();
commands.Add("/exit");
var listOfString = commands.Select(Regex.Escape).ToList();
var joinTheWords = string.Join("|", listOfString);
var regexPattern = $@"\b({joinTheWords})\b";
var theRegex= new Regex(regexPattern, RegexOptions.IgnoreCase);
Console.WriteLine(theRegex);
Console.WriteLine(theRegex.Match(@"/exit").Success);
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
Upvotes: 1
Views: 2993
Reputation: 149
a not so clean way (but simple) to find words with forward slashes is to replace the forward slash with accepted (but never used string), and use that in your regex search:
str = "this is a search string with /exit and/exit";
key = "/exit";
value="/EXIT";
str = str.replace(/\//gi, "_a_a_");
k = key.replace(/\//gi, "_a_a_");
var regex = new RegExp('\\b' + k + '\\b', "g");
str = str.replace(regex, value) ;
str = str.replace("_a_a_","/");
console.log(str);
Upvotes: 0
Reputation: 7361
At the beginning of the string "/exit", there's no word boundary /b
because "/" isn't a letter, number, or underscore. (there's a word boundary just after the "/")
you could roll your own "smart word boundary" to include matching these forward slashes as valid "word" characters:
(?:((?<!/)\B(?=/))|\b(?=\w))
In English, this means that you must have either a "NON word boundary followed by a slash that doesn't have any preceding slashes" (?<!/)\B(?=/)
, OR "a regular word boundary, provided you can 'see' an alphanumeric after it" \b(?=\w)
. By using a \B
with "/", we can get "pseudo word boundary" behavior:
var commands = new List<string>();
commands.Add("/exit");
List<String> listOfString = commands.Select(Regex.Escape).ToList();
String joinTheWords = string.Join("|", listOfString);
var regexPattern = $@"(?:(?:(?<!/)\B)(?=/)|\b(?=\w))({joinTheWords})\b";
var theRegex = new Regex(regexPattern, RegexOptions.IgnoreCase);
Console.WriteLine(theRegex);
Console.WriteLine(theRegex.Match("/exit").Success);
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
There may (and probably are) more simple ways to approach this, especially if you can "preprocess" the list of pattern fragments first to replace special characters with a static tokens, match with regular \b
's, then replace them back.
Upvotes: 1
Reputation:
Since you already know the /
is included in all the words,
you can factor them out of your command list.
Change commands.Add("/exit");
to this commands.Add("exit");
Then do as normal, escaping metachars and joining.
Then, since you only care that /
is not preceded with a /
all
thats needed in the beginning is(?<!/)/
.
As for the end, I'd use a conditional word boundary (?(?<=\w)\b)
.
I mean, that's all you really need.
Putting it all together, the regex line would be:
var regexPattern = $@"(?<!/)(/(?:{joinTheWords}))(?(?<=\w)\b)";
Upvotes: 1