Why is this Regex.Match failing? - c#

I have this little method to look for the 3-digit number in a string and increment it by one. The types of strings I am passing in are like CP1-P-CP2-004-D and MOT03-C-FP04-003.
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
foreach (char c in alphabet)
{
m = Regex.Match(s, #"\d{3}(?=[" + c + "-]|$)");
}
if (m.Success)
{
int i = Convert.ToInt32(m.Value); i += 1;
Console.WriteLine(s + " - " + i.ToString("D3"));
}
else { Console.WriteLine(s + " - No success"); }
EDIT: Initially I just had this; to test out my Regex.Match case:
Match m = Regex.Match(s, #"\d{3}(?=[A-]|$)");
And it worked with CP1PCP2001A no worries, but when I updated it, and tried CP1PCP2001C it returned "No Success", while CP1PCP2001 works no problem. Can anyone tell me why this is?

Have you tried
m = Regex.Match(s, #"\d{3}(?=[A-Z\-]|$)");
[A-Z] means that it can be any of the capital letters between A and Z thus eliminating the need for char[] alphabet, and the \- allows you to add the '-' as a parameter, without causing conflict with the first parameter.

From the comments, we're looking for "the first 3 digit number (coming from the right)". Here's a literal implementation:
m = Regex.Match(s, #"\d{3}", RegexOptions.RightToLeft);
This is more permissive towards unexpected characters than the other answers. You can decide whether that's good or bad for your application.

re-write the code this way
bool matched = false;
foreach (char c in alphabet)
{
m = Regex.Match(s, #"\d{3}(?=[" + c + "-]|$)");
if (m.Success)
{
int i = Convert.ToInt32(m.Value); i += 1;
Console.WriteLine(s + " - " + i.ToString("D3"));
matched=true;
break;
}
}
if(!matched)
Console.WriteLine(s + " - No success");
a better way would be not to loop and specify the char range to match in regex itself
example
m = Regex.Match(s, #"\d{3}(?=[A-Z\-]|$)");
if (m.Success)
{
int i = Convert.ToInt32(m.Value); i += 1;
Console.WriteLine(s + " - " + i.ToString("D3"));
}
else
Console.WriteLine(s + " - No success");
regex demo here

Related

Converting boundary points from a .kml using regex

I have this boundary that I received from a kml, I was able to dig down the xml and grab just the boundary points. I need to convert the points from this :
-92.25968002689014,30.7180061776264,0 -92.25976564548085,30.71751889774971,0 -92.25992462712097,30.71670626485147,0 -92.26006418327708,30.71604891951008,0 -92.26018466460856,30.71558863525373,0 -92.26037301574165,30.71498469610939,0 -92.26054805030229,30.71444051930294,0 -92.26065861561004,30.71411636559884,0
To This:
POLYGON((-92.25968002689014 30.7180061776264, -92.25976564548085,30.71751889774971, -92.25992462712097 30.71670626485147, -92.26006418327708,30.71604891951008, -92.26018466460856 30.71558863525373, -92.26037301574165,30.71498469610939, -92.26054805030229 30.71444051930294, -92.26065861561004,30.71411636559884))
The regex pattern I am using is : ",[0-9.-]* *"
My plan was to use a regex replace to replace any commas followed by any number of digits, periods, or minus signs followed by one or more spaces with some character like a colon. Then replace all commas with spaces and then replae all colons with commas. But for some reason I can't get it to work. Any Advice would be greatly appreciated.
You can try this:
([-\d.]+),([-\d.]+),([-\d.]+)\s+([-\d.]+),([-\d.]+),([-\d.]+)\s*;
Sample c# code:
String polygon(String input)
{
string pattern = #"([-\d.]+),([-\d.]+),([-\d.]+)\s+([-\d.]+),([-\d.]+),([-\d.]+)\s*";
RegexOptions options = RegexOptions.Singleline | RegexOptions.Multiline;
String finalString = "POLYGON((";
int count = 0;
foreach (Match m in Regex.Matches(input, pattern, options))
{
if (count > 0)
finalString += ",";
finalString += m.Groups[1] + " " + m.Groups[2] + ", " + m.Groups[4] + "," + m.Groups[5];
count = 1;
}
finalString += "))";
return finalString;
}
output:
POLYGON((-92.25968002689014 30.7180061776264, -92.25976564548085,30.71751889774971,-92.25992462712097 30.71670626485147,
-92.26006418327708,30.71604891951008,-92.26018466460856 30.71558863525373, -92.26037301574165,30.71498469610939,-92.260
54805030229 30.71444051930294, -92.26065861561004,30.71411636559884))

How can I count how many lowercase, uppercase and other characters I have in my string properly?

My code here represents the counting of all lowercase and uppercase letter, but I'm having trouble counting all other characters. Other characters consist of spaces and symbols like '!#$^%$'. Anything that isn't lowercase or uppercase refers to other.
However, my problem is that my other is counting uppercase and I can't seem to work the code out.
I do not know where I'm going wrong so any help would be appreciated, thanks!
Console.WriteLine("Enter a sentence: ");
string sentence = Console.ReadLine();
int countUpper = 0, countLower=0, countOther=0, i;
for (i = 0; i < sentence.Length;i++ )
{
if (char.IsUpper(sentence[i])) countUpper++;
if (char.IsLower(sentence[i])) countLower++;
if (!(char.IsLower(sentence[i]) || (!(char.IsUpper(sentence[i]))))) countOther++;
}
Console.WriteLine("Lower: " + countLower);
Console.WriteLine("Upper: " + countUpper);
Console.WriteLine("Other: " + countOther);
Try using if / else if / else instead:
Console.WriteLine("Enter a sentence: ");
string sentence = Console.ReadLine();
int countUpper = 0, countLower=0, countOther=0, i;
for (i = 0; i < sentence.Length;i++ )
{
if (char.IsUpper(sentence[i])) countUpper++;
else if (char.IsLower(sentence[i])) countLower++;
else countOther++;
}
Console.WriteLine("Lower: " + countLower);
Console.WriteLine("Upper: " + countUpper);
Console.WriteLine("Other: " + countOther);
To count specific characters, simple Regex can be used instead analyzing char by char:
string sentence = "testTESTING#,";
int countLower = Regex.Matches(sentence, #"\p{Ll}").Count;
int countUpper = Regex.Matches(sentence, #"\p{Lu}").Count;
int countOther = Regex.Matches(sentence, #"\W").Count;
// \p{category} - In that Unicode category
// category = Lu - Letter, uppercase
// category = Ll - letter, lowercase
// \W = non word character
Simple specification ".Net framework regular expressions quick reference" can be downloaded from http://www.microsoft.com/en-us/download/details.aspx?id=43119
I think countOther would just be string.Length - countUpper - countLower.

regEx to wrap string case insensitive

I am a complete newbie when it comes to Regular Expressions, and was wondering if somebody could help me out. I'm not sure if using a regEx is the correct approach here, so please feel free to chime in if you have a better idea. (I will be looping thru many strings).
Basically, I'd like to find/replace on a string, wrapping the matches with {} and keeping the original case of the string.
Example:
Source: "The CAT sat on the mat."
Find/Replace: "cat"
Result: "The {CAT} sat on the mat."
I would like the find/replace to work on only the first occurance, and I also need to know whether the find/replace did indeed match or not.
I hope I've explained things clearly enough.
Thank you.
Regex theRegex =
new Regex("(" + Regex.Escape(FindReplace) + ")", RegexOptions.IgnoreCase);
theRegex.Replace(Source, "{$1}", 1);
If you want word boundary tolerance:
Regex theRegex =
(#"([\W_])(" + Regex.Escape(FindReplace) + #")([\W_])", RegexOptions.IgnoreCase)
theRegex.Replace(str, "$1{$2}$3", 1)
If you will be looping through many strings, then perhaps Regex might not be the best idea - it's a great tool, but not the fastest.
Here's a sample code that would also work:
var str = "The Cat ate a mouse";
var search = "cat";
var index = str.IndexOf(search, StringComparison.CurrentCultureIgnoreCase);
if (index == -1)
throw new Exception("String not found"); //or do something else in this case here
var newStr = str.Substring(0, index) + "{" + str.Substring(index, search.Length) + "}" + str.Substring(index + search.Length);
EDIT:
As noted in the comments, the above code has some issues.
So I decided to try and find a way to make it work without using Regex. Don't get me wrong, I love Regex as much as the next guy. I did this mostly out of curiosity. ;)
Here's what I came upon:
public static class StringExtendsionsMethods
{
public static int IndexOfUsingBoundary(this String s, String word)
{
var firstLetter = word[0].ToString();
StringBuilder sb = new StringBuilder();
bool previousWasLetterOrDigit = false;
int i = 0;
while (i < s.Length - word.Length + 1)
{
bool wordFound = false;
char c = s[i];
if (c.ToString().Equals(firstLetter, StringComparison.CurrentCultureIgnoreCase))
if (!previousWasLetterOrDigit)
if (s.Substring(i, word.Length).Equals(word, StringComparison.CurrentCultureIgnoreCase))
{
wordFound = true;
bool wholeWordFound = true;
if (s.Length > i + word.Length)
{
if (Char.IsLetterOrDigit(s[i + word.Length]))
wholeWordFound = false;
}
if (wholeWordFound)
return i;
sb.Append(word);
i += word.Length;
}
if (!wordFound)
{
previousWasLetterOrDigit = Char.IsLetterOrDigit(c);
sb.Append(c);
i++;
}
}
return -1;
}
}
But I can't take credit for this! I found this after some Googling here, on StackOverflow and then modified it. ;)
Use this method instead of the standard IndexOf in the above code.
Try this:
class Program
{
const string FindReplace = "cat";
static void Main(string[] args)
{
var input = "The CAT sat on the mat as a cat.";
var result = Regex
.Replace(
input,
"(?<=.*)" + FindReplace + "(?=.*)",
m =>
{
return "{" + m.Value.ToUpper() + "}";
},
RegexOptions.IgnoreCase);
Console.WriteLine(result);
}
}

Find string in text, remove the first and last char

I search in a text for some strings and want to remove the first and last char in those strings.
Example :
...
...
OK 125 ab_D9 "can be "this" or; can not be "this" ";
...
OK 673 e_IO1_ "hello; is strong
or maybe not strong";
...
So I use the code to find all strings begin with OK and remove from the 4 groups "...":
tmp = fin.ReadToEnd();
var matches = Regex.Matches(tmp, "(OK) ([0-9]+) ([A-Za-z_0-9]+) (\"(?:(?!\";).)*\");", RegexOptions.Singleline);
for (int i = 0; i < matches.Count; i++)
{
matches[i].Groups[4].Value.Remove(0);
matches[i].Groups[4].Value.Remove(matches[i].Groups[4].Value.ToString().Length - 1);
Console.WriteLine(matches[i].Groups[1].Value + "\r\n" + "\r\n" + "\r\n" + matches[i].Groups[2].Value + "\r\n" + "\r\n" + matches[i].Groups[3].Value + "\r\n" + "\r\n" + "\r\n" + matches[i].Groups[4].Value);
Console.WriteLine(" ");
}
But it doesn't remove first and last char from Group 4. What did I do wrong?
My Result should be:
OK
125
ab_D9
can be "this" or; can not be "this"
OK
673
e_IO1
hello; is strong
or maybe not strong
There is no need to remove things. Just don't capture the quotes in the first place. So move the parentheses one character inward.
"(OK) ([0-9]+) ([A-Za-z_0-9]+) \"((?:(?!\";).)*)\";"
You should assign the result of Substring() and Remove() methods. they do not change the existing string but return the changed string which you need to assign to the same or some other string variable. Check the code:
tmp = fin.ReadToEnd();
var matches = Regex.Matches(tmp, "(OK) ([0-9]+) ([A-Za-z_0-9]+) (\"(?:(?!\";).)*\");", RegexOptions.Singleline);
for (int i = 0; i < matches.Count; i++)
{
string str = matches[i].Groups[4].Value.Substring(0);
str = str.Remove(str.Length - 1);
Console.WriteLine(matches[i].Groups[1].Value + "\r\n" + "\r\n" + "\r\n" + matches[i].Groups[2].Value + "\r\n" + "\r\n" + matches[i].Groups[3].Value + "\r\n" + "\r\n" + "\r\n" + str);
Console.WriteLine(" ");
}
P.S. You should use Environment.NewLine instead of "\r\n", it's the better approach.

How does MatchEvaluator in Regex.Replace work?

This is the input string 23x * y34x2. I want to insert " * " (star surrounded by whitespaces) after every number followed by letter, and after every letter followed by number. So my output string would look like this: 23 * x * y * 34 * x * 2.
This is the regex that does the job: #"\d(?=[a-z])|[a-z](?=\d)". This is the function that I wrote that inserts the " * ".
Regex reg = new Regex(#"\d(?=[a-z])|[a-z](?=\d)");
MatchCollection matchC;
matchC = reg.Matches(input);
int ii = 1;
foreach (Match element in matchC)//foreach match I will find the index of that match
{
input = input.Insert(element.Index + ii, " * ");//since I' am inserting " * " ( 3 characters )
ii += 3; //I must increment index by 3
}
return input; //return modified input
My question how to do same job using .net MatchEvaluator? I am new to regex and don't understand good replacing with MatchEvaluator. This is the code that I tried to wrote:
{
Regex reg = new Regex(#"\d(?=[a-z])|[a-z](?=\d)");
MatchEvaluator matchEval = new MatchEvaluator(ReplaceStar);
input = reg.Replace(input, matchEval);
return input;
}
public string ReplaceStar( Match match )
{
//return What??
}
A MatchEvaluator is a delegate that takes a Match object and returns a string that should be replaced instead of the match. You can also refer to groups from the match. You can rewrite your code as follows:
string input = "23x * y34x2";
Regex reg = new Regex(#"\d(?=[a-z])|[a-z](?=\d)");
string result = reg.Replace(input, delegate(Match m) {
return m.Value + " * ";
});
To give an example of how this works, the first time the delegate is called, Match parameter will be a match on the string "3". The delegate in this case is defined to return the match itself as a string concatenated with " * ". So the first "3" is replaced with "3 * ".
The process continues in this way, with delegate being called once for each match in the original string.

Categories

Resources