Compare String with Regex in C# - c#

I have a list of string taken from a file. Some of this strings are in the format "Q" + number + "null" (e.g. Q98null, Q1null, Q24null, etc)
With a foreach loop I must check if a string is just like the one shown before.
I use this right now
string a = "Q9null" //just for testing
if(a.Contains("Q") && a.Contains("null"))
MessageBox.Show("ok");
but I'd like to know if there is a better way to do this with regex.
Thank you!

Your method will produce a lot of false positives - for example, it would recognize some invalid strings, such as "nullQ" or "Questionable nullability".
A regex to test for the match would be "^Q\\d+null$". The structure is very simple: it says that the target string must start in a Q, then one or more decimal digits should come, and then there should be null at the end.
Console.WriteLine(Regex.IsMatch("Q123null", "^Q\\d+null$")); // Prints True
Console.WriteLine(Regex.IsMatch("nullQ", "^Q\\d+null$")); // Prints False
Demo.

public static bool Check(string s)
{
Regex regex = new Regex(#"^Q\d+null$");
Match match = regex.Match(s);
return match.Success;
}
Apply the above method in your code:
string a = "Q9null" //just for testing
if(Check(a))
MessageBox.Show("ok");

First way: Using the Regex
Use this Regex ^Q\d+null$
Second way: Using the SubString
string s = "Q1123null";
string First,Second,Third;
First = s[0].ToString();
Second = s.Substring(1,s.Length-5);
Third = s.Substring(s.Length-4);
Console.WriteLine (First);
Console.WriteLine (Second);
Console.WriteLine (Third);
then you can check everything after this...

Related

Compare if input string is in correct format

Check if input string entered by user is in format like IIPIII, where I is integer number, any one digit number can be used on place of I and P is a character.
Example if input is 32P125 it is valid string else N23P33 is invalid.
I tried using string.Length or string.IndexOf("P") but how to validate other integer values?
I'm sure someone can offer a more succinct answer but pattern matching is the way to go.
using System.Text.RegularExpressions;
string test = "32P125";
// 2 integers followed by any upper cased letter, followed by 3 integers.
Regex regex = new Regex(#"\d{2}[A-Z]\d{3}", RegexOptions.ECMAScript);
Match match = regex.Match(test);
if (match.Success)
{
//// Valid string
}
else
{
//// Invalid string
}
Considering that 'P' has to matched literally -
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string st1 = "32P125";
string st2 = "N23P33";
Regex rg = new Regex(#"\d{2}P\d{3}");
// If 'P' is not to be matched literally, reeplace above line with below one
// Regex rg = new Regex(#"\d{2}[A-Za-z]\d{3}");
Console.WriteLine(rg.IsMatch(st1));
Console.WriteLine(rg.IsMatch(st2));
}
}
OUTPUT
True
False
It can be encapsulated in one simple if:
string testString = "12P123";
if(
// check if third number is letter
Char.IsLetter(testString[2]) &&
// if above succeeds, code proceeds to second condition (short-circuiting)
// remove third character, after that it should be a valid number (only digits)
int.TryParse(testString.Remove(2, 1), out int i)
) {...}
I would encourage the usage of MaskedTextProvided over Regex.
Not only is this looking cleaner but it's also less error prone.
Sample code would look like the following:
string Num = "12P123";
MaskedTextProvider prov = new MaskedTextProvider("##P###");
prov.Set(Num);
var isValid = prov.MaskFull;
if(isValid){
string result = prov.ToDisplayString();
Console.WriteLine(result);
}
Use simple Regular expression for this kind of stuff.

Check array for string that starts with given one (ignoring case)

I am trying to see if my string starts with a string in an array of strings I've created. Here is my code:
string x = "Table a";
string y = "a table";
string[] arr = new string["table", "chair", "plate"]
if (arr.Contains(x.ToLower())){
// this should be true
}
if (arr.Contains(y.ToLower())){
// this should be false
}
How can I make it so my if statement comes up true? Id like to just match the beginning of string x to the contents of the array while ignoring the case and the following characters. I thought I needed regex to do this but I could be mistaken. I'm a bit of a newbie with regex.
It seems you want to check if your string contains an element from your list, so this should be what you are looking for:
if (arr.Any(c => x.ToLower().Contains(c)))
Or simpler:
if (arr.Any(x.ToLower().Contains))
Or based on your comments you may use this:
if (arr.Any(x.ToLower().Split(' ')[0].Contains))
Because you said you want regex...
you can set a regex to var regex = new Regex("(table|plate|fork)");
and check for if(regex.IsMatch(myString)) { ... }
but it for the issue at hand, you dont have to use Regex, as you are searching for an exact substring... you can use
(as #S.Akbari mentioned : if (arr.Any(c => x.ToLower().Contains(c))) { ... }
Enumerable.Contains matches exact values (and there is no build in compare that checks for "starts with"), you need Any that takes predicate that takes each array element as parameter and perform the check. So first step is you want "contains" to be other way around - given string to contain element from array like:
var myString = "some string"
if (arr.Any(arrayItem => myString.Contains(arrayItem)))...
Now you actually asking for "string starts with given word" and not just contains - so you obviously need StartsWith (which conveniently allows to specify case sensitivity unlike Contains - Case insensitive 'Contains(string)'):
if (arr.Any(arrayItem => myString.StartsWith(
arrayItem, StringComparison.CurrentCultureIgnoreCase))) ...
Note that this code will accept "tableAAA bob" - if you really need to break on word boundary regular expression may be better choice. Building regular expressions dynamically is trivial as long as you properly escape all the values.
Regex should be
beginning of string - ^
properly escaped word you are searching for - Escape Special Character in Regex
word break - \b
if (arr.Any(arrayItem => Regex.Match(myString,
String.Format(#"^{0}\b", Regex.Escape(arrayItem)),
RegexOptions.IgnoreCase)) ...
you can do something like below using TypeScript. Instead of Starts with you can also use contains or equals etc..
public namesList: Array<string> = ['name1','name2','name3','name4','name5'];
// SomeString = 'name1, Hello there';
private isNamePresent(SomeString : string):boolean{
if (this.namesList.find(name => SomeString.startsWith(name)))
return true;
return false;
}
I think I understand what you are trying to say here, although there are still some ambiguity. Are you trying to see if 1 word in your String (which is a sentence) exists in your array?
#Amy is correct, this might not have to do with Regex at all.
I think this segment of code will do what you want in Java (which can easily be translated to C#):
Java:
x = x.ToLower();
string[] words = x.Split("\\s+");
foreach(string word in words){
foreach(string element in arr){
if(element.Equals(word)){
return true;
}
}
}
return false;
You can also use a Set to store the elements in your array, which can make look up more efficient.
Java:
x = x.ToLower();
string[] words = x.Split("\\s+");
HashSet<string> set = new HashSet<string>(arr);
for(string word : words){
if(set.contains(word)){
return true;
}
}
return false;
Edit: (12/22, 11:05am)
I rewrote my solution in C#, thanks to reminders by #Amy and #JohnyL. Since the author only wants to match the first word of the string, this edited code should work :)
C#:
static bool contains(){
x = x.ToLower();
string[] words = x.Split(" ");
var set = new HashSet<string>(arr);
if(set.Contains(words[0])){
return true;
}
return false;
}
Sorry my question was so vague but here is the solution thanks to some help from a few people that answered.
var regex = new Regex("^(table|chair|plate) *.*");
if (regex.IsMatch(x.ToLower())){}

String format Check gives unexpected result (Regex)

I want to check format of a string which is ABC-nnn, where ABC represents alphabets (English) in capital letters. nnn represents triple digit number for example 123 or 001 or 012 A complete example would be FBI-026. I used regex for that and below is my code.
public bool IsSubstringMatchingFormat(int numberOfLettersBeforeHyphen, int numberOfNumbersAfterHyphen, string stringToMatch)
{
Regex regex = new Regex($#"^[A-Z]{numberOfLettersBeforeHyphen}-\d{numberOfNumbersAfterHyphen}");
return regex.IsMatch(stringToMatch);
}
I call it IsSubstringMatchingFormat(3, 3, "SMB-123") but it returns false. Please provide your insight.
Have you actually checked what the string you are passing into the regex looks like? ie evaluate $#"^[A-Z]{numberOfLettersBeforeHyphen}-\d{numberOfNumbersAfterHyphen}"and see if that is the regex you want? I can tell you that it isn't because it will end up being ^[A-Z]3-\d3 which does not do what you want.
What I think you'll want is:
$#"^[A-Z]{{{numberOfLettersBeforeHyphen}}}-\d{{{numberOfNumbersAfterHyphen}}}"
This adds the escaped curly braces back into your regex to give:
^[A-Z]{3}-\d{3}
The equivalent of this using String.Format would be:
String.Format(
#"^[A-Z]{{{0}}}-\d{{{1}}}",
numberOfLettersBeforeHyphen,
numberOfLettersAfterHyphen);
Your curly braces are being consumed by the string interpolation and are not making it into the regex. If you try to print the regex, you'll see it's something like
^[A-Z]3-\d3
Which is something else entirely.
The {} are being removed when you format. Try this:
public static bool IsSubstringMatchingFormat(int numberOfLettersBeforeHyphen, int numberOfNumbersAfterHyphen, string stringToMatch)
{
var expre = #"^[A-Z]{numberOfLettersBeforeHyphen}-\d{numberOfNumbersAfterHyphen}";//
expre = expre.Replace("numberOfLettersBeforeHyphen", numberOfLettersBeforeHyphen.ToString())
.Replace("numberOfNumbersAfterHyphen", numberOfNumbersAfterHyphen.ToString());
Regex regex = new Regex(expre);
return regex.IsMatch(stringToMatch);
}

C# Regex.Replace - search for matches in replacement string as well

Given the following:
string input = "xSxSx";
var result = Regex.Replace(input, "xSx", "xTx");
// result == "xTxSx"
It looks like the replacement string is not used for further matching, which is why we don't get the expected "xTxTx".
How to solve that? Is there some kind of special notation to tell the engine to find for a second match using the string with the first replacement already in place?
That's because, once a character is matched, it won't be matched again. So, 2nd time the string to match is Sx and not xSx.
You would need to use look-arounds here:
Regex.Replace(input, "(?<=x)S(?=x)", "T");
This will replace the S which is both preceded and succeeded by x with a T. Since look-arounds are 0-length assertion, they will not consume x.
Just use a loop for anything more complex that you can't simplify into a look[ahead/behind].
string test = "xSxSx";
string result = string.Empty;
while(true) {
result = Regex.Replace(test, "xSx", "xTx");
if(result != test)
test = result;
else
break;
}

C# Regex - if string only contains a character

Using C#/Regex, how do I find a string that only contains commas and no alphanumeric (or other non-comma) symbols?
a: ',,,,,,,' match
b: ',,,,,,#A' no match
[^,]
If that matches, that means a string contains a non-comma character.
A more complete example:
if (!Regex.IsMatch(yourTestString, "[^,]"))
{
// This string does NOT contain commas
}
This should do it:
var text = ",,,";
Regex.IsMatch(text, #"^,+$"); // true
If I read your question correctly, you want to know if a string contains only commas.
If so, use this regex: ^[,]+$.
This will only match on strings that contain one or more commas and nothing else.
A string of only commas?
Regex.IsMatch(str, #"^,*$");
That will tell you whether or not str consists entirely of commans or not.
I'd suggest that, as a one-char regex will always have to examine each character of its input string in the worst case, a simple for-loop will definitely be more efficient. Something like this will give the exact same effect in less time and space than any equivalent Regex:
private void IsOnlyOneChar(string input, char c)
{
for (var i = 0; i < input.Length; ++i)
if (input[i] != c)
return false;
return true;
}
Not literally the answer you were looking for, but in my opinion this is your optimal solution.

Categories

Resources