Consider the following:
string keywords = "(load|save|close)";
Regex x = new Regex(#"\b"+keywords+"\b");
I get no matches. However, if I do this:
Regex x = new Regex(#"\b(load|save|close)\b");
I get matches. How come the former doesn't work, and how can I fix this? Basically, I want the keywords to be configurable so I placed them in a string.
The last \b in the first code snippet needs a verbatim string specifier (#) in front of it as well as it is a seperate string instance.
string keywords = "(load|save|close)";
Regex x = new Regex(#"\b"+keywords+#"\b");
You're missing another verbatim string specifier (# prefixed to the last \b):
Regex x = new Regex(#"\b" + keywords + #"\b");
Regex x = new Regex(#"\b"+keywords+#"\b");
You forgot additional # before second "\b"
Related
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();
}
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.
regex demo
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)";
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);
I am trying to extract all of the text (shown as xxxx) in the follow pattern:
Session["xxxx"]
using c#
This may be Request.Querystring["xxxx"] so I am trying to build the expression dynamically. When I do so, I get all sorts of problems about unescaped charecters or no matches :(
an example might be:
string patternstart = "Session[";
string patternend = "]";
string regexexpr = #"\\" + patternstart + #"(.*?)\\" + patternend ;
string sText = "Text to be searched containing Session[\"xxxx\"] the result would be xxxx";
MatchCollection matches = Regex.Matches(sText, #regexexpr);
Can anyone help with this as I am stumped (as I always seem to be with RegEx :) )
With some little modifications to your code.
string patternstart = Regex.Escape("Session[");
string patternend = Regex.Escape("]");
string regexexpr = patternstart + #"(.*?)" + patternend;
The pattern you construct in your example looks something like this:
\\Session[(.*?)\\]
There are a couple of problems with this. First it assumes the string starts with a literal backslash, second, it wraps the entire (.*?) in a character class, that means it will match any single open parenthesis, period, asterisk, question mark, close parenthesis or backslash. You'd need to escape the the brackets in your pattern, if you want to match a literal [.
You could use a pattern like this:
Session\[(.*?)]
For example:
string regexexpr = #"Session\[(.*?)]";
string sText = "Text to be searched containing Session[\"xxxx\"] the result would be xxxx";
MatchCollection matches = Regex.Matches(sText, #regexexpr);
Console.WriteLine(matches[0].Groups[1].Value); // "xxxx"
The characters [ and ] have a special meaning with regular expressions - they define a group where one of the contained characters must match. To work around this, simply 'escape' them with a leading \ character:
string patternstart = "Session\[";
string patternend = "\]";
An example "final string" could then be:
Session\["(.*)"\]
However, you could easily write your RegEx to handle Session, Querystring, etc automatically if you require (without also matching every other array you throw at it), and avoid having to build up the string in the first place:
(Querystring|Session|Form)\["(.*)"\]
and then take the second match.
I have a fairly long string that contains sub strings with the following format:
project[1]/someword[1]
project[1]/someotherword[1]
There will be about 10 or so instances of this pattern in the string.
What I want to do is to be able to replace the second integer in square brackets with a different one. So the string would look like this for instance:
project[1]/someword[2]
project[1]/someotherword[2]
I''m thinking that regular expressions are what I need here. I came up with the regex:
project\[1\]/.*\[([0-9])\]
Which should capture the group [0-9] so I can replace it with something else. I'm looking at MSDN Regex.Replace() but I'm not seeing how to replace part of a string that is captured with a value of your choosing. Any advice on how to accomplish this would be appreciated. Thanks much.
*Edit: * After working with #Tharwen some I have changed my approach a bit. Here is the new code I am working with:
String yourString = String yourString = #"<element w:xpath=""/project[1]/someword[1]""/> <anothernode></anothernode> <another element w:xpath=""/project[1]/someotherword[1]""/>";
int yourNumber = 2;
string anotherString = string.Empty;
anotherString = Regex.Replace(yourString, #"(?<=project\[1\]/.*\[)\d(?=\]"")", yourNumber.ToString());
Matched groups are replaced using the $1, $2 syntax as follows :-
csharp> Regex.Replace("Meaning of life is 42", #"([^\d]*)(\d+)", "$1($2)");
"Meaning of life is (42)"
If you are new to regular expressions in .NET I recommend http://www.ultrapico.com/Expresso.htm
Also http://www.regular-expressions.info/dotnet.html has some good stuff for quick reference.
I've adapted yours to use a lookbehind and lookahead to only match a digit which is preceded by 'project[1]/xxxxx[' and followed by ']':
(?<=project\[1\]/.*\[)\d(?=\]")
Then, you can use:
String yourString = "project[1]/someword[1]";
int yourNumber = 2;
yourString = Regex.Replace(yourString, #"(?<=project\[1\]/.*\[)\d(?=\]"")", yourNumber.ToString());
I think maybe you were confused because Regex.Replace has lots of overloads which do slightly different things. I've used this one.
If you want to process the value of a captured group before replacing it, you'll have to separate the different parts of the string, make your modifications and put them back together.
string test = "project[1]/someword[1]\nproject[1]/someotherword[1]\n";
string result = string.Empty;
foreach (Match match in Regex.Matches(test, #"(project\[1\]/.*\[)([0-9])(\]\n)"))
{
result += match.Groups[1].Value;
result += (int.Parse(match.Groups[2].Value) + 1).ToString();
result += match.Groups[3].Value;
}
If you just want to replace text verbatim, it's easier: Regex.Replace(test, #"abc(.*)cba", #"cba$1abc").
you can use String.Replace (String, String)
for example
String.Replace ("someword[1]", "someword[2]")
RegEx has always confused me.
I have a string like this:
IDE\DiskDJ205GA20_____________________________A3VS____\5&1003ca0&0&0.0.0
Or Sometimes stored like this:
IDE\DiskSJ305GA23_____________________________PG33S\6&2003Sa0&0&0.0.0
I want to get the 'A3VS' or 'PG33S' string. It's my firmware and is varied in length and type. I used to use:
string[] split = PNP.Split('\\'); //where PHP is my string name
var start = split[1].LastIndexOf('_');
string mystring = split[1].Substring(start + 1);
But that only works for strings that don't end with __ after the firmware string. I noticed that some have an additional random '_' after it.
Is RegEx the way to solve this? Or is there another way better
just without RegEx it can be expressed like this:
var firmware = PNP.Split(new[] {'_'}, StringSplitOptions.RemoveEmptyEntries)[1].Split('\\')[0];
string s = split[1].TrimEnd('_');
string mystring = s.Substring(s.LastIndexOf('_') + 1);
If you want the RegEX way to do it here it is:
Regex regex = new Regex(#"\\.*_+(?<firmware>[A-Za-z0-9]+)_*\\");
var m1 = regex.Match("IDE\DiskSJ305GA23_____________________________PG33S\6&2003Sa0&0&0.0.0");
var g1 = m1.Groups["firmware"].Value;
//g1 == "PG33S"
Keep in mind you have to use [A-Za-z0-9] instead of \w in the capture subexpression since \w also matches an underscore (_).
i have a problem in string manipulation
here is the code
string str = "LDAP://company.com/OU=MyOU1 Control,DC=MyCompany,DC=com";
Regex regex = new Regex("OU=\\w+");
var result = regex.Matches(str);
var strList = new List<string>();
foreach (var item in result)
{
strList.Add(item.ToString().Remove(0,3));
}
Console.WriteLine(string.Join("/",strList));
the result i am getting is "MyOU1" instead of getting "MyOU1 Control"
please help thanks
If you want the space character to be matched as well, you need to include it in your regex. \w only matches word charactes, which does not include spaces.
Regex regex = new Regex(#"OU=[\w\s]+");
This matches word characters (\w) and whitespace characters (\s).
(The # in front of the string is just for convenience: If you use it, you don't need to escape backslashes.)
Either add space to the allowed list (\w doesn't allow space) or use the knowledge that comma can be used as a separator.
Regex regex = new Regex("OU=(\\w|\\s)+");
OR
Regex regex = new Regex("OU=[^,]+");