Extra delimiter in MAC Address reformat - c#

I've looked at several questions on here about formatting and validating MAC addresses, which is where I developed my regex from. The problem I'm having is that when I go to update the field is that there are extra delimiters in the new formatted MAC or if no delimiter exists the MAC fails to validate. I'm new to using regex, so can someone clarify why this is happening?
if (checkMac(NewMacAddress.Text) == true)
{
string formattedMAC = NewMacAddress.Text;
formattedMAC.Replace(" ", "").Replace(":", "").Replace("-", ""); //attempt to remove the delimiters before formatting
var regex = "(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})";
var replace = "$1:$2:$3:$4:$5:$6";
var newformat = Regex.Replace(formattedMAC, regex, replace);
NewMacAddress.Text = newformat.ToString();
}
Here is the checkmac function
protected bool checkMac(string macaddress)
{
macaddress.Replace(" ", "").Replace(":", "").Replace("-", "");
Regex r = new Regex("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$");
if (r.Match(macaddress).Success)
{
return true;
}
else
{
return false;
}
}
This is sample output for the extra delimiter that I was talking about. 00::5:0::56::b:f:00:7f
I was able to get the original MAC from a textbox. This also occurs with the MAC address I get from screen scrapes.

The reason your code is not working as intended is because:
String.Replace does not modify the string you pass in, but returns a new string instead (strings are immutable). You have to assign the result of String.Replace to a variable.
Your checkMac function only allows mac addresses with delimiters. You can simply remove this restriction to resolve your problems.
The working code then becomes something along the lines of:
string newMacAddress = "00::5:0::56::b:f:00:7f";
if (checkMac(newMacAddress) == true)
{
string formattedMAC = newMacAddress;
formattedMAC = formattedMAC.Replace(" ", "").Replace(":", "").Replace("-", ""); //attempt to remove the delimiters before formatting
var regex = "(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})";
var replace = "$1:$2:$3:$4:$5:$6";
var newformat = Regex.Replace(formattedMAC, regex, replace);
newMacAddress = newformat.ToString();
}
protected static bool checkMac(string macaddress)
{
macaddress = macaddress.Replace(" ", "").Replace(":", "").Replace("-", "");
Regex r = new Regex("^([0-9A-Fa-f]{12})$");
if (r.Match(macaddress).Success)
{
return true;
}
else
{
return false;
}
}

You're close. I'm first going to answer using Ruby because that's what I'm most familiar with at the moment, and it should be sufficient for you to understand how to get it working in C#. Maybe I can convert it to C# later.
using these elements:
\A - start of entire string
[0-9a-fA-F] - any hex digit
{2} - twice
[:-]? - either ":" or "-" or "" (no delimiter)
\Z - end of entire string, before ending newline if it exists
() - parenthetical match in order to reference parts of the regex, e.g. match[1]
This regex will do what you need:
mac_address_regex = /\A([0-9a-fA-F]{2})[:-]?([0-9a-fA-F]{2})[:-]?([0-9a-fA-F]{2})[:-]?([0-9a-fA-F]{2})[:-]?([0-9a-fA-F]{2})[:-]?([0-9a-fA-F]{2})\Z/
You can both validate and sanitize input using this regex:
match = mac_address_regex.match(new_mac_address.text)
if match.present?
sanitized_mac_addr = (1..6).map { |i| match[i] }.join(":") # join match[i] for i = (1,2,3,4,5,6)
sanitized_mac_addr.upcase! # uppercase
else
sanitized_mac_addr = nil
end

Related

Replace and remove a string via regex

This is first time I am working with regex.
The string below
var value ="abc ltd as yes"
need to be change to
var value ="abc Limited"
I have the following code:
public static string Attempt_Prefix_Removal( string prefix, string replacement, bool remove = false)
{
if (remove == true)
{
var yesy = $"(?<!prefix )" + prefix + ".*";
var test = Regex.Replace(prefix.ToLower(), $"(?<!prefix )" + prefix + ".*", replacement );
}
var output = (remove == true) ? Regex.Replace(prefix.ToLower(), $"(?<!prefix )" + prefix + ".*", replacement) : Regex.Replace(prefix.ToLower(), $"(?<!prefix )" + prefix + "", replacement);
return output;
}
the values that are passed to the method are
prefix ="ltd", replacement = "Limited" , remove = ture
after running the code the result is
abc Limited as yes
what do i need to change to get ride of as yes ??
thanks
You may leverage this code:
var prefix ="ltd"; var replacement = "Limited";
var pat = $#"(?s)(?<!\w){Regex.Escape(prefix)}(?!\w){remove ? ".*" : string.Empty}";
return Regex.Replace(val, pat, replacement.Replace("$", "$$"));
See the C# demo online
The main points here are:
(?s) - will allow . match a newline (in case you will use .* in the pattern)
(?<!\w){Regex.Escape(prefix)}(?!\w) - the (?<!\w) negative lookbehind will fail the match if the current location is preceded with a word char (you may further tweak the lookbehind pattern as per your requirements)
{remove ? ".*" : string.Empty} - this will either append .* (if remove is true) or not.
private string regexOp(string sentence, string word, string wordtoReplace, bool isRemove)
{
var retValue = sentence;
if (isRemove)
{
var Pattern = "^.*?(?=" + word + ")";
Match result = Regex.Match(sentence, #Pattern);
if (!string.IsNullOrEmpty(result.Value))
retValue = result + wordtoReplace;
}
else
retValue = Regex.Replace(sentence, word, wordtoReplace);
return retValue;
}
try this method, this will work as you expected with dynamic,
do not forget to mark it as answer if this really helped you,

my regex work on online test but not in my c# app

I have a regex pattern (?<=base64,)(.*?)(?=") to get part of text.
This pattern works in an online tester web site, but in my C# app always returns false in IsMatch() and return empty in Match().
string imga = _blogPosts[position].PostImage;
if (_blogPosts[position].PostImage !=null)
{
Regex re2 = new Regex(#"(?<=base64,)(.*?)(?="")");
bool m = re2.IsMatch(imga); // always retun false
}
Can anyone help me?
reg pic
What you copied into RegexStorm is just the debugger row data. There is no actual " in your string.
Note that there is no sense using the regex for this task, you might as well use
if (imga !=null && imga.Contains("base64,")) { /* yes */ }
If you need to actually grab all non-whitespace characters after base64, substring, you might use
Regex re2 = new Regex(#"base64,(\S+)");
Match m = re2.Match(imga);
string result = "";
if (m.Success)
{
result = m.Groups[1].Value;
}
See the regex demo used above. (\S+) captures into Group 1 any one or more non-whitespace chars after a base64, substring.
But you can really get it using a Substring:
string result = "";
if (imga !=null && imga.Contains("base64,"))
{
result = imga.Substring(imga.IndexOf("base64,")+7);
}

replacing characters in a single field of a comma-separated list

I have string in my c# code
a,b,c,d,"e,f",g,h
I want to replace "e,f" with "e f" i.e. ',' which is inside inverted comma should be replaced by space.
I tried using string.split but it is not working for me.
OK, I can't be bothered to think of a regex approach so I am going to offer an old fashioned loop approach which will work:
string DoReplace(string input)
{
bool isInner = false;//flag to detect if we are in the inner string or not
string result = "";//result to return
foreach(char c in input)//loop each character in the input string
{
if(isInner && c == ',')//if we are in an inner string and it is a comma, append space
result += " ";
else//otherwise append the character
result += c;
if(c == '"')//if we have hit an inner quote, toggle the flag
isInner = !isInner;
}
return result;
}
NOTE: This solution assumes that there can only be one level of inner quotes, for example you cannot have "a,b,c,"d,e,"f,g",h",i,j" - because that's just plain madness!
For the scenario where you only need to match one pair of letters, the following regex will work:
string source = "a,b,c,d,\"e,f\",g,h";
string pattern = "\"([\\w]),([\\w])\"";
string replace = "\"$1 $2\"";
string result = Regex.Replace(source, pattern, replace);
Console.WriteLine(result); // a,b,c,d,"e f",g,h
Breaking apart the pattern, it is matching any instance where there is a "X,X" sequence where X is any letter, and is replacing it with the very same sequence, with a space in between the letters instead of a comma.
You could easily extend this if you needed to to have it match more than one letter, etc, as needed.
For the case where you can have multiple letters separated by commas within quotes that need to be replaced, the following can do it for you. Sample text is a,b,c,d,"e,f,a",g,h:
string source = "a,b,c,d,\"e,f,a\",g,h";
string pattern = "\"([ ,\\w]+),([ ,\\w]+)\"";
string replace = "\"$1 $2\"";
string result = source;
while (Regex.IsMatch(result, pattern)) {
result = Regex.Replace(result, pattern, replace);
}
Console.WriteLine(result); // a,b,c,d,"e f a",g,h
This does something similar compared to the first one, but just removes any comma that is sandwiched by letters surrounded by quotes, and repeats it until all cases are removed.
Here's a somewhat fragile but simple solution:
string.Join("\"", line.Split('"').Select((s, i) => i % 2 == 0 ? s : s.Replace(",", " ")))
It's fragile because it doesn't handle flavors of CSV that escape double-quotes inside double-quotes.
Use the following code:
string str = "a,b,c,d,\"e,f\",g,h";
string[] str2 = str.Split('\"');
var str3 = str2.Select(p => ((p.StartsWith(",") || p.EndsWith(",")) ? p : p.Replace(',', ' '))).ToList();
str = string.Join("", str3);
Use Split() and Join():
string input = "a,b,c,d,\"e,f\",g,h";
string[] pieces = input.Split('"');
for ( int i = 1; i < pieces.Length; i += 2 )
{
pieces[i] = string.Join(" ", pieces[i].Split(','));
}
string output = string.Join("\"", pieces);
Console.WriteLine(output);
// output: a,b,c,d,"e f",g,h

How to replace the text between two characters in c#

I am bit confused writing the regex for finding the Text between the two delimiters { } and replace the text with another text in c#,how to replace?
I tried this.
StreamReader sr = new StreamReader(#"C:abc.txt");
string line;
line = sr.ReadLine();
while (line != null)
{
if (line.StartsWith("<"))
{
if (line.IndexOf('{') == 29)
{
string s = line;
int start = s.IndexOf("{");
int end = s.IndexOf("}");
string result = s.Substring(start+1, end - start - 1);
}
}
//write the lie to console window
Console.Write Line(line);
//Read the next line
line = sr.ReadLine();
}
//close the file
sr.Close();
Console.ReadLine();
I want replace the found text(result) with another text.
Use Regex with pattern: \{([^\}]+)\}
Regex yourRegex = new Regex(#"\{([^\}]+)\}");
string result = yourRegex.Replace(yourString, "anyReplacement");
string s = "data{value here} data";
int start = s.IndexOf("{");
int end = s.IndexOf("}", start);
string result = s.Substring(start+1, end - start - 1);
s = s.Replace(result, "your replacement value");
To get the string between the parentheses to be replaced, use the Regex pattern
string errString = "This {match here} uses 3 other {match here} to {match here} the {match here}ation";
string toReplace = Regex.Match(errString, #"\{([^\}]+)\}").Groups[1].Value;
Console.WriteLine(toReplace); // prints 'match here'
To then replace the text found you can simply use the Replace method as follows:
string correctString = errString.Replace(toReplace, "document");
Explanation of the Regex pattern:
\{ # Escaped curly parentheses, means "starts with a '{' character"
( # Parentheses in a regex mean "put (capture) the stuff
# in between into the Groups array"
[^}] # Any character that is not a '}' character
* # Zero or more occurrences of the aforementioned "non '}' char"
) # Close the capturing group
\} # "Ends with a '}' character"
The following regular expression will match the criteria you specified:
string pattern = #"^(\<.{27})(\{[^}]*\})(.*)";
The following would perform a replace:
string result = Regex.Replace(input, pattern, "$1 REPLACE $3");
For the input: "<012345678901234567890123456{sdfsdfsdf}sadfsdf" this gives the output "<012345678901234567890123456 REPLACE sadfsdf"
You need two calls to Substring(), rather than one: One to get textBefore, the other to get textAfter, and then you concatenate those with your replacement.
int start = s.IndexOf("{");
int end = s.IndexOf("}");
//I skip the check that end is valid too avoid clutter
string textBefore = s.Substring(0, start);
string textAfter = s.Substring(end+1);
string replacedText = textBefore + newText + textAfter;
If you want to keep the braces, you need a small adjustment:
int start = s.IndexOf("{");
int end = s.IndexOf("}");
string textBefore = s.Substring(0, start-1);
string textAfter = s.Substring(end);
string replacedText = textBefore + newText + textAfter;
the simplest way is to use split method if you want to avoid any regex .. this is an aproach :
string s = "sometext {getthis}";
string result= s.Split(new char[] { '{', '}' })[1];
You can use the Regex expression that some others have already posted, or you can use a more advanced Regex that uses balancing groups to make sure the opening { is balanced by a closing }.
That expression is then (?<BRACE>\{)([^\}]*)(?<-BRACE>\})
You can test this expression online at RegexHero.
You simply match your input string with this Regex pattern, then use the replace methods of Regex, for instance:
var result = Regex.Replace(input, "(?<BRACE>\{)([^\}]*)(?<-BRACE>\})", textToReplaceWith);
For more C# Regex Replace examples, see http://www.dotnetperls.com/regex-replace.

C# Regex to replace invalid character to make it as perfect float number

for example if the string is "-234.24234.-23423.344"
the result should be "-234.2423423423344"
if the string is "898.4.44.4"
the result should be "898.4444"
if the string is "-898.4.-"
the result should be "-898.4"
the result should always make scene as a double type
What I can make is this:
string pattern = String.Format(#"[^\d\{0}\{1}]",
NumberFormatInfo.CurrentInfo.NumberDecimalSeparator,
NumberFormatInfo.CurrentInfo.NegativeSign);
string result = Regex.Replace(value, pattern, string.Empty);
// this will not be able to deal with something like this "-.3-46821721.114.4"
Is there any perfect way to deal with those cases?
It's probably a bad idea, but you can do this with regex like this:
Regex.Replace(input, #"[^-.0-9]|(?<!^)-|(?<=\..*)\.", "")
The regex matches:
[^-.0-9] # anything which isn't ., -, or a digit.
| # or
(?<!^)- # a - which is not at the start of the string
| # or
(?<=\..*)\. # a dot which is not the first dot in the string
This works on your examples, and additionally this case: "9-1.1" becomes "91.1".
You could also change (?<!^)- to (?<!^[^-.0-9]*)- if you'd like "asd-8" to become "-8" rather than "8".
It's not a good idea using regex itself to achieve your goal, since regex lack AND and NOT logic for expression.
Try the code below, it will do the same thing.
var str = #"-.3-46821721.114.4";
var beforeHead = "";
var afterHead = "";
var validHead = new Regex(#"(\d\.)" /* use #"\." if you think "-.5" is also valid*/, RegexOptions.Compiled);
Regex.Replace(str, #"[^0-9\.-]", "");
var match = validHead.Match(str);
beforeHead = str.Substring(0, str.IndexOf(match.Value));
if (beforeHead[0] == '-')
{
beforeHead = '-' + Regex.Replace(beforeHead, #"[^0-9]", "");
}
else
{
beforeHead = Regex.Replace(beforeHead, #"[^0-9]", "");
}
afterHead = Regex.Replace(str.Substring(beforeHead.Length + 2 /* 1, if you use \. as head*/), #"[^0-9]", "");
var validFloatNumber = beforeHead + match.Value + afterHead;
String must be trimmed before operation.

Categories

Resources