I want to match comma separate integer list using Regex. I have used bellow pattern but it doesn't work for me.
if (!Regex.IsMatch(textBox_ImportRowsList.Text, #"^([0-9]+(,[0-9]+))*"))
{
errorProvider1.SetError(label_ListRowPosttext, "Row Count invalid!");
}
Valid Inputs:
1
1,2
1,4,6,10
Invalid Inputs:
1,
1.1
1,A
2,/,1
,1,3
use this regular expression:
^\d+(,\d+)*$
EDIT
Best way to validate your comma separated string is
string someString = "1,2,3";
bool myResults = someString.Split(';').
Any<string>(s => !isNumeric(s));
if(myResults)
Console.Writeln("invalid number");
else
Console.Writeln("valid number");
public bool isNumeric(string val)
{
if(val == String.Empty)
return false;
int result;
return int.TryParse(val,out result);
}
The following might also work for you. This regex will also capture an empty string.
^(\d+(,\d+)*)?$
or
^\d+(,\d+)*$
start with an integer, so '\d+'. That is 1 or more digit characters ('0'-'9')
Then make a set of parenthesis which contains ',\d+' and put an asterisk after it. allow the , and digit
You've got the asterisk in the wrong place. Instead of this:
#"^([0-9]+(,[0-9]+))*"
...use this:
#"^([0-9]+(,[0-9]+)*)"
Additionally, you should anchor the end like you did the beginning, and don't really need the outermost set of parentheses:
#"^[0-9]+(,[0-9]+)*$"
You could use ^\d+(,\d+)*$ but as #Lazarus has pointed out, this may be a case where regex is a bit of a overkill and string.Split() would be better utilized you could even use this with a int.tryParse if you are trying to manipulate numbers.
you can try with this code
List<string> list = new List<string>();
list.Add("1");
list.Add("1.1");
list.Add("1,A");
list.Add("2,/,1");
foreach (var item in list)
{
if (!Regex.IsMatch(item, #"^([0-9](,[0-9])*)$"))
{
Console.WriteLine("no match :" + item);
}
}
try this one
String strInput = textBox_ImportRowsList.Text;
foreach (String s in strInput.Split(new[]{',', ' '}, StringSplitOptions.RemoveEmptyEntries))
{
if(!Regex.IsMatch(s, #"^\d+(,\d+)*$"))
{
errorProvider1.SetError(label_ListRowPosttext, "Row Count invalid!");
}
}
Related
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())){}
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...
Good morning! Hoping someone can help me out here with some pattern matching.
What I want to do is match a string of numbers against a bunch of text. The only catch is that I DO NOT want to match anything that has more numbers to the left and/or right of the number I'm looking for (letters are fine).
Here is some code that works, but it seems that having three IsMatch calls is overkill. Problem is, I can't figure out how to reduce it to just one IsMatch call.
static void Main(string[] args)
{
List<string> list = new List<string>();
list.Add("cm1312nfi"); // WANT
list.Add("cm1312"); // WANT
list.Add("cm1312n"); // WANT
list.Add("1312"); // WANT
list.Add("13123456"); // DON'T WANT
list.Add("56781312"); // DON'T WANT
list.Add("56781312444"); // DON'T WANT
list.Add(" cm1312nfi "); // WANT
list.Add(" cm1312 "); // WANT
list.Add("cm1312n "); // WANT
list.Add(" 1312"); // WANT
list.Add(" 13123456"); // DON'T WANT
list.Add(" 56781312 "); // DON'T WANT
foreach (string s in list)
{
// Can we reduce this to just one IsMatch() call???
if (s.Contains("1312") && !(Regex.IsMatch(s, #"\b[0-9]+1312[0-9]+\b") || Regex.IsMatch(s, #"\b[0-9]+1312\b") || Regex.IsMatch(s, #"\b1312[0-9]+\b")))
{
Console.WriteLine("'{0}' is a match for '1312'", s);
}
else
{
Console.WriteLine("'{0}' is NOT a match for '1312'", s);
}
}
}
Thank you in advance for any help you can provide!
~Mr. Spock
You can use negative lookarounds for a single check:
#"(?<![0-9])1312(?![0-9])"
(?<![0-9]) makes sure that 1312 doesn't have a digit before it, (?![0-9]) makes sure there's no digit after 1312.
You can make the character classes optional matches:
if (s.Contains("1312") && !Regex.IsMatch(s, #"\b[0-9]*1312[0-9]*\b"))
{
....
Have a look on the amazing Regexplained: http://tinyurl.com/q62uqr3
To catch invalid patterns use:
Regex.IsMatch(s, #"\b[0-9]*1312[0-9]*\b")
Also [0-9] can be replaced with \d
You can select only those letters before, after, or none at all
#"\b[a-z|A-Z]*1312[a-z|A-Z]*\b"
For curious minds - Another approach at solving the above problem?
foreach (string s in list)
{
var rgx = new Regex("[^0-9]");
// Remove all characters other than digits
s=rgx.Replace(s,"");
// Can we reduce this to just one IsMatch() call???
if (s.Contains("1312") && CheckMatch(s))
{
Console.WriteLine("'{0}' is a match for '1312'", s);
}
else
{
Console.WriteLine("'{0}' is NOT a match for '1312'", s);
}
}
private static bool CheckMatch(string s)
{
var index = s.IndexOf("1312");
// Check if no. of characters to the left of '1312' is same as no. of characters to its right
if(index == s.SubString(index).Length()-4)
return true;
return false;
}
Considering not a match for "131213121312".
I have a string, where the "special areas" are enclosed in curly braces:
{intIncG}/{intIncD}/02-{yy}
I need to iterate through all of these elements inbetween {} and replace them based on their content. What is the best code structure to do it in C#?
I can't just do a replace since I need to know the index of each "speacial area {}" in order to replace it with the correct value.
Regex rgx = new Regex( #"\({[^\}]*\})");
string output = rgx.Replace(input, new MatchEvaluator(DoStuff));
static string DoStuff(Match match)
{
//Here you have access to match.Index, and match.Value so can do something different for Match1, Match2, etc.
//You can easily strip the {'s off the value by
string value = match.Value.Substring(1, match.Value.Length-2);
//Then call a function which takes value and index to get the string to pass back to be susbstituted
}
string.Replace will do just fine.
var updatedString = myString.Replace("{intIncG}", "something");
Do once for every different string.
Update:
Since you need the index of { in order to produce the replacement string (as you commented), you can use Regex.Matches to find the indices of { - each Match object in the Matches collection will include the index in the string.
Use Regex.Replace:
Replaces all occurrences of a character pattern defined by a regular expression with a specified replacement character string.
from msdn
You can define a function and join it's output -- so you'll only need to traverse the parts once and not for every replace rule.
private IEnumerable<string> Traverse(string input)
{
int index = 0;
string[] parts = input.Split(new[] {'/'});
foreach(var part in parts)
{
index++;
string retVal = string.Empty;
switch(part)
{
case "{intIncG}":
retVal = "a"; // or something based on index!
break;
case "{intIncD}":
retVal = "b"; // or something based on index!
break;
...
}
yield return retVal;
}
}
string replaced = string.Join("/", Traverse(inputString));
I currently have the following loop:
do {
checkedWord = articleWords.Dequeue().TrimEnd('?', '.', ',', '!');
correct = _spellChecker.CheckWord(checkedWord);
} while (correct && articleWords.Count > 0);
I am queuing up the words from an array that was split from a textbox with ' ' as the separator. The loop works fine, except for I don't want any blank entries "" or really anything non alpha-numeric to stop the loop. Currently if there's more than one space between the words then the loop ends and it continues on to get word suggestions from the spellchecker.
If I do while (correct && articleWords.Count > 0 || checkedWord == ""); then it'll skip any blank queue entries, but it still hangs up on things like new lines - so if the textbox that it loads from contains a couple of paragraphs it screws up at the newline separating the two. I've also tried while (correct && articleWords.Count > 0 || !Char.IsLetterOrDigit(checkedWord, 0)); but that also doesn't work.
Question 1: Can you group conditions like (statement1 == true && count > 0) || (statement1 == false && Char.IsLetterOrDigit(char))? - Meaning that all of the conditions in the first grouping must be met OR all of the conditions in the second set must be.
Question 2: I want my loop to continue progressing until an actual spelling error is found, and for it to ignore things like empty queue entries, as well as anything that's not an alpha-numeric character at the beginning of the string.
I suspect that I'm close with the Char.IsLetterOrDigit bit, but have to figure out how to do it correctly.
Let me know if more info is required.
Thanks!
You should not use composite loop condition, a good practice is usage while loop with easy general condition and 'break' in loop body when you should leave it.
You can use some thing like this:
public void Test()
{
var separators = new[] { ' ', '\t', '\r', '\x00a0', '\x0085', '?', ',', '.', '!' };
var input = "Test string, news112! news \n next, line! error in error word";
var tokens = new Queue<string>(input.Split(separators, StringSplitOptions.RemoveEmptyEntries));
string currentWord = null;
while (tokens.Any())
{
currentWord = tokens.Dequeue();
if (currentWord.All(c => Char.IsLetterOrDigit(c)))
{
if (!CheckSpell(currentWord))
{
break;
}
}
}
}
public bool CheckSpell(string word)
{
return word != null && word.Length > 0 && word[0] != 'e';
}
If your goal is to find the first error, you can skip the while loop and do the following:
var firstError = tokens.Where(t => t.All(Char.IsLetterOrDigit) && !_spellChecker.CheckWord(t)).FirstOrDefault();
So long as you have a valid boolean expression, you can do that without an issue. This is something that is very easy to test.
To use Char.IsLetterOrDigit you will need to loop over each character in the string and test it.
When it comes to text selections you should use regular expressions. It is very powerfull and fast framework for text queries. It is capable of doing it's job with O(n) complexity. It helps you because you don't have to think how you will select your text values you just specify what you need
Try this code. The pattern part #"\w+" means that I want to select all groups of alphanumeric symbols whose length > 1. If I'd wanted to select all words that start with letter 't' than I would write #"t\w+".
using System;
using System.Text;
using System.Text.RegularExpressions;
namespace Test
{
class Program
{
static void Main(string[] args)
{
string str = "The quick brown fox jumps over the lazy dog";
Regex regex = new Regex(#"\w+", RegexOptions.Compiled);
for (Match match = regex.Match(str); match.Success; match = match.NextMatch())
{
Console.WriteLine(match.Value);
}
}
}
}
Q1. Absolutely. Just make sure your groupings are properly separated.
Q2. For performance and clarity, I would use REGEX to clean your input before queuing:
using System.Text.RegularExpressions;
...
string input = GetArticle(); // or however you get your input
input = Regex.Replace(input, #"[^0-9\w\s]", string.Empty);
// not sure what your separators but you can always
// reduce multiple spaces to a single space and just split
// on the single space
var articleWords = new Queue<string>(input.Split( ... ));
do {
checkedWord = articleWords.Dequeue();
// put your conditional grouping here if you want
if(!_spellChecker.CheckWord(checkedWord)) {
// only update "correct" if necessary - writes are more expensive =)
// although with the "break" below you shouldn't need "correct" anymore
// correct = false;
// in case you want to raise an event - it's cleaner =)
OnSpellingError(checkWord);
// if you want to stop looping because of the error
break;
}
}
while(articleWords.Count > 0);
I wouldn't use Char.IsLetterOrDigit as I think that would be slower...besides, with the REGEX in the beginning you should have taken care of the entries that aren't characters or digits.
EDIT Adding LINQ response
On second thought, I think you're just trying to find spelling errors so how about this?
using System.Text.RegularExpressions;
...
string input = GetArticle(); // or however you get your input
// clean up words from punctuation
input = Regex.Replace(input, #"[^0-9\w\s]", string.Empty);
// trim whitespace
input = Regex.Replace(c, #"\s+", #" ");
var errors = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).All(w => !_spellChecker.CheckWord(w));
Then you can just do whatever you want with the errors =) Or you can just use a .Any if you just want to know whether there exists a spelling mistake at all.
Q1: Sure, it's possible to group conditions like that.
Q2: What about something like this?
string[] articleWords = textBoxText.Split(' ');
articleWords = articleWords.Select(a => a.Trim()).ToArray(); // remove all whitespaces (blanks, linebreaks)
articleWords = articleWords.Where(a => !string.IsNullOrEmpty(a)).ToArray(); // remove empty strings
bool correct = false;
bool spellingErrorFound = false;
for (int i = 0; i < articleWords.Length; i++)
{
string checkedWord = articleWords[i].TrimEnd('?', '.', ',', '!');
correct = _spellChecker.CheckWord(checkedWord);
if (!correct)
spellingErrorFound = true;
}