How to replace a string in this case? - c#

I'm implementing a filter.
I store the filter criteria in a list of string. e.g.
List filters
A filter logic as a string e.g.
String filterLogic = "(1 AND 2) OR 3";
Now I want to replace the numbers with the filter criteria, e.g.
(filters[1] AND filters[2]) OR filters[3])
//stores all the filter criterias
List<String> filters = new List<string>();
for (int i = 1; i <= controlGroupId;i++ )
{
StringBuilder sb = new StringBuilder();
String fieldsDropdownId="dlFields"+i;
DropDownList dlFields = (DropDownList)this.FindControl(fieldsDropdownId);
sb.Append(dlFields.SelectedValue);
String operatorDropdownId = "dlOperator" + i;
DropDownList dlOperator = (DropDownList)this.FindControl(operatorDropdownId);
String operatorValue = dlOperator.SelectedValue;
String valuetxbId = "txb" + i;
TextBox tb = (TextBox)this.FindControl(valuetxbId);
String textboxValue = tb.Text;
switch (operatorValue)
{
case "=":
sb.Append("=");
sb.Append(textboxValue);
break;
case "<>":
sb.Append("<>");
sb.Append(textboxValue);
break;
case "<":
sb.Append("<");
sb.Append(textboxValue);
break;
case ">":
sb.Append(">");
sb.Append(textboxValue);
break;
case ">=":
sb.Append(">=");
sb.Append(textboxValue);
break;
case "<=":
sb.Append("<=");
sb.Append(textboxValue);
break;
case "contains":
sb.Append(" Like ");
sb.Append("'%");
sb.Append(textboxValue);
sb.Append("%'");
break;
case "does not contain":
sb.Append(" Not Like ");
sb.Append("'%");
sb.Append(textboxValue);
sb.Append("%'");
break;
case "starts with":
sb.Append(" Like ");
sb.Append("'");
sb.Append(textboxValue);
sb.Append("%'");
break;
}
filters.Add(sb.ToString());
}
Update:
List<String> l = new List<string>();
for (int i = 1; i < 12; i++)
{
String s="hello"+i;
l.Add(s);
}
String ss = "(1 AND 2 AND 3 AND 4 AND 5 AND 6 AND 7 AND 8 AND 9 AND 10 AND 11)";
Regex rgx = new Regex(#"\d+");
ss=rgx.Replace(ss, "l[$0]");
This gives me :
"(l[1] AND l[2] AND l[3] AND l[4] AND l[5] AND l[6] AND l[7] AND l[8] AND l[9] AND l[10] AND l[11])"
What I want is:
(hello1 AND hello2 AND hello3 AND hello4 AND hello5 AND hello6 AND hello7 AND hello8 AND hello9 AND hello10 AND hello11)";

Given all integers are indices, one can do the following:
Regex rgx = new Regex (#"\d+");
rgx.Replace(fitlerLogic, "filters[$0]");
Then the result is:
"filters[1] AND filters[2]) OR filters[3]"
But this only works if all integers should be replaced with filter indices.
You also made by the way a typo: it's filterLogic, not fitlerLogic.
EDIT: or if you want to substitute it with the real value, you can use a lambda-expression:
object[] filter = new object[] {false,true,false,true};//not that an array is 0-indexed
Regex rgx = new Regex (#"\d+");
rgx.Replace (fitlerLogic,x => filter[int.Parse(x.Value)].ToString());
In that case the result is:
"(True AND False) OR True"
If you however wish to evaluate the expression, I would take a look to compiler-compilers and context-free grammars.

Related

Regex Error in Switch Statements

I want to create a program that takes in a string and output just the numbers, hopefully using regex to save effort, here is the following code i have
public void main{
string str = "abc-123.44def";
string output = "";
bool setA = false;
StringBuilder stb = new StringBuilder();
for(int i=0; i<str.Length; i++){
switch(str[i]){
case 'b':
setA = foo();
break;
case 'c':
foo2();
break;
case '\d':
case '-':
case '.':
if(setA){
stb.Append(str[i]);
}
break;
default:
break;
}
}
output = stb.toString();
}
public void foo(){
return true;
}
Problem is, the editor gives me a error saying
Unrecognized Escape Sequence
on the '\d' part. Ive seen online sample codes where such usage is allowed so im not sure why my editor is not accepting this. Can someone explain to me what the problem is and how to solve it?
EDIT: It seems like my sample was alittle misleading. I cannot just take out the numbers from the strings by itself since other characters in the string calls different functions and the number characters i want to take out depends on some of them. I updated the code to correct the misinformation.
You can use the Char.IsDigit() to check if a char is a digit (as I mentioned in my first comment):
string str = "abc-123.44def";
string output = "";
bool setA = false;
StringBuilder stb = new StringBuilder();
for(int i=0; i<str.Length; i++){
switch(str[i]){
case 'b':
setA = foo();
break;
case 'c':
foo2();
break;
// case '\d': REMOVE IT
case '-':
case '.':
if(setA){
stb.Append(str[i]);
}
break;
default:
if (Char.IsDigit(str[i])) stb.Append(str[i]); // Add this
break;
}
}
output = stb.ToString();
}
Result:
Is this what you are looking for ?
Regex r = new Regex(#"\d+");
string s = "abc-123.44def";
var matches = r.Matches(s);
List<string> numbersOnly = new List<string>();
foreach (Match match in matches)
numbersOnly.Add(match.Value);
foreach (var number in numbersOnly)
Console.WriteLine(number);
//output:
//123
//44

C#, how to make list<int> and functional if statements [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am a novice C# user, and I am experimenting with lists in Csharp's console application. This list contains 10 numbers, and the order of these numbers are randomized. What I want to do is to make specific text for a specific number which if statements will handle.
For example: If number == 0, the text "Hello" will show up. Or if the number == 3, the text "Goodbye" will show up.
I tried a few things but I got problems like repeated text: http://i.imgur.com/8sCbeLn.jpg?1
Random r = new Random();
int tempValue;
List<int> number = new List<int>();
number.Add(0);
number.Add(1);
number.Add(2);
number.Add(3);
number.Add(4);
number.Add(5);
number.Add(6);
number.Add(7);
number.Add(8);
number.Add(9);
for (int i = 0; i < 10; i++)
{
tempValue = r.Next(0, number.Count);
Console.WriteLine(number[tempValue]);
number.RemoveAt(tempValue);
Console.ReadLine();
}
Please help me getting on the right track.
You can for example use a switch to select strings from a value.
If you get repeated values, I suspect that you used tempValue to select the string, you have to use number[tempValue]:
string text = null;
switch (number[tempValue]) {
case 0: text = "Hello"; break;
case 1: text = "How do you do"; break;
case 2: text = "Howdie"; break;
case 3: text = "Goodbye"; break;
case 4: text = "Bye"; break;
case 5: text = "Hello again"; break;
case 6: text = "Good day"; break;
case 7: text = "Have fun"; break;
case 8: text = "Greatings"; break;
case 9: text = "Goodbye again"; break;
}
Why not add 10 random numbers to a list and then loop through the list, and print using you if statements
Random r = new Random();
List<int> nums= new List<int>();
int numForList = r.Next(0,10);
bool numInList = true;
//add 10 random numbers to a list
for(int i=0;i<10;i++)
{
do
{
if(!nums.Contains(numForList))
{
numInList = false;
nums.Add(numForList);
}
else
{
numForList = r.Next(0,10);
}
} while (numInList == true);
numInList = true;
}
foreach(var num in nums)
{
switch (num)
{
case 0: Console.WriteLine("Hello"); break;
case 1: Console.WriteLine("How do you do"); break;
... //Add more cases here for each possible random number
}
}

C# count ocurrences of several char in string using regex.Matches.count once

Having a string like:
0x1TTTT10TT1Tx01Tx1001xxx100T0TxT1T1TxTxTxx0TT0000000x0xTxT1Tx0T0x10x1
I want to get:
0 appears 20
1 appears 12
x appears 17
T appears 21
If I use
int zero = Regex.Matches(input, "0").Count;
int one = Regex.Matches(input, "1").Count;
int x = Regex.Matches(input, "x").Count;
int T = Regex.Matches(input, "T").Count;
How to accomplish same result using more efficient approach using Regex?
This is not really the real purpose of Regular Expressions. I would instead advise the use of a loop over the characters, like the following:
int zeroCount = 0;
int oneCount = 0;
int xCount = 0;
int tCount = 0;
foreach(var ch in input)
{
switch(ch)
{
case '0':
zeroCount++;
break;
case '1':
oneCount++;
break;
case 'x':
xCount++;
break;
case 'T':
tCount++;
break;
}
}
Unfortunately the most efficient isn't usually the most concise.

Efficient method for converting text to phone keypad

I have the following code for converting a string containing alphanumeric characters to a string of numbers that can be entered into a phone using the phone's keypad:
string text = "sometext containing spaces and numbers 12345";
Dictionary<char, char> alphabetMapping = new Dictionary<char, char>();
alphabetMapping['a'] = '2';
alphabetMapping['b'] = '2';
alphabetMapping['c'] = '2';
alphabetMapping['d'] = '3';
alphabetMapping['e'] = '3';
alphabetMapping['f'] = '3';
alphabetMapping['g'] = '4';
alphabetMapping['h'] = '4';
alphabetMapping['i'] = '4';
alphabetMapping['j'] = '5';
alphabetMapping['k'] = '5';
alphabetMapping['l'] = '5';
alphabetMapping['m'] = '6';
alphabetMapping['n'] = '6';
alphabetMapping['o'] = '6';
alphabetMapping['p'] = '7';
alphabetMapping['q'] = '7';
alphabetMapping['r'] = '7';
alphabetMapping['s'] = '7';
alphabetMapping['t'] = '8';
alphabetMapping['u'] = '8';
alphabetMapping['v'] = '8';
alphabetMapping['w'] = '9';
alphabetMapping['x'] = '9';
alphabetMapping['y'] = '9';
alphabetMapping['z'] = '9';
alphabetMapping['1'] = '1';
alphabetMapping['2'] = '2';
alphabetMapping['3'] = '3';
alphabetMapping['4'] = '4';
alphabetMapping['5'] = '5';
alphabetMapping['6'] = '6';
alphabetMapping['7'] = '7';
alphabetMapping['8'] = '8';
alphabetMapping['9'] = '9';
alphabetMapping['0'] = '0';
alphabetMapping['.'] = '0';
alphabetMapping[','] = '0';
alphabetMapping['#'] = '0';
alphabetMapping['*'] = '*';
alphabetMapping['#'] = '#';
alphabetMapping[' '] = '0'; // not sure if this underscore or space
StringBuilder sb = new StringBuilder();
foreach (var c in text)
{
sb.Append(alphabetMapping[c]);
}
Console.WriteLine(sb.ToString());
The output:
76638398026682464640772237026306862377012345
Not that this has much practical use, but some automated phone systems ask for passwords that may contain letters so I wrote this code for helping with that.
Is there a more efficient method for this or am I on the right track?
An elegant way to convert phone letters to their respective numbers is to use Regular Expressions. Here is the function that I use. It may need to be tweaked to fit your scenario.
internal static string ConvertPhoneTexttoNumber(string PhoneNumber)
{
PhoneNumber = Regex.Replace(PhoneNumber, #"[abcABC]", "2");
PhoneNumber = Regex.Replace(PhoneNumber, #"[defDEF]", "3");
PhoneNumber = Regex.Replace(PhoneNumber, #"[ghiGHI]", "4");
PhoneNumber = Regex.Replace(PhoneNumber, #"[jklJKL]", "5");
PhoneNumber = Regex.Replace(PhoneNumber, #"[mnoMNO]", "6");
PhoneNumber = Regex.Replace(PhoneNumber, #"[pgrsPGRS]", "7");
PhoneNumber = Regex.Replace(PhoneNumber, #"[tuvTUV]", "8");
PhoneNumber = Regex.Replace(PhoneNumber, #"[wxyzWXYZ]", "9");
//remove all non alphanumeric characters
PhoneNumber = Regex.Replace(PhoneNumber, #"[\W]", "");
return PhoneNumber;
}
This solution will work for any number of characters in a string. If you want to keep the parentheses and dashes remove this line:
PhoneNumber = Regex.Replace(PhoneNumber, #"[\W]", "");
Note: If you don't know how to use Regular Expressions, here is a great tutorial:
https://regexone.com/lesson/introduction_abcs
You could use fewer lines of code if you grouped all of your items together.
var allValues = new List<KeyValuePair<string,char>>()
allValues.Add(new KeyValuePair("abc2","2"));
allValues.Add(new KeyValuePair("def3","3"));
etc, etc
StringBuilder sb = new StringBuilder();
foreach (var c in text)
{
var matched = allValues.FirstOrDefault(kvp=> kvp.Key.Contains(c));
if(matched != null)
{
sb.Append(matched.Value);
}
else
{
sb.Append(" ");
}
}
Console.WriteLine(sb.ToString());
It's probably not computationally more efficient, but it's less for a human to read.
Considering the size of the dataset (alphanumeric characters and letters) and the intended application, this seems like the most logical and seemingly optimal way to do it. If you wanted to improve the performance you could use a HashSet, but I'm not sure you would see any measurable gain from that with this dataset.

C# Switch results to list then to comma separated values

How would I make a switch statement populate a list, or comma delimited string?
For example
switch(test)
{
case 0:
"test"
break;
case 1:
"test2"
break;
case 2:
"test3"
break;
}
So my program will go into this statement multiple times. So lets say it goes in there twice and has case 2 and case 1. I woulld like a string value containing the following:
string value = "test3, test2"
Looks like a List<string> would be ideal to hold your values, you can create a comma separated string from that using string.Join():
List<string> myList = new List<string>();
//add items
myList.Add("test2");
//create string from current entries in the list
string myString = string.Join("," myList);
By multiple times, you mean a loop? You can just have a string and concatenate the string using + operator, or you can just have a list and add to it everytime the case condition is satisfied.
But if you mean by conditional flow so that you want case 0, 1 and 2 to all be evaluated, then you can simply omit the break and do the same concatenation like I mentioned above.
private string strValue = string.Empty;
private string StrValue
{
get
{
return strValue ;
}
set
{
StrValue= string.Concat(strValue , ",", value);
}
}
switch(test)
{
case 0:
StrValue = "test"
break;
case1:
StrValue = "test2"
break;
case 2:
StrValue = "test3"
breakl
}
Where ever you used StrValue remove "," if "," comes in the last.
There's a couple ways you can do it, a very simple one is:
string csv = "";
while (yourCriteria) {
string value;
// insert code to get your test value
switch(test)
{
case 0:
value = "test";
break;
case1:
value = "test2";
break;
case 2:
value = "test3";
break;
}
csv += value + ", ";
}
csv = csv.Length > 0 ? csv.Substring(0, csv.Length-2) : "";
Use a loop and a StringBuilder. If you're doing repeated concatenation, StringBuilders are significantly more efficient than naive string concatenation with +.
StringBuilder sb = new StringBuilder();
for(...)
{
switch(test)
{
case 0:
sb.Append("test");
break;
case1:
sb.Append("test2");
break;
case 2:
sb.Append("test3");
break;
}
}

Categories

Resources