Substring with dynamic length - c#

I need to get value of below string into 2 variables.
Input
6.3-full-day-care
Expected output:
var price=6.3; //The input is dynamic.Cannot get fixed length
var serviceKey="full-day-care";
How can I do that? Substring doesn't help here.

You can use String.Split and String.Substring methods like;
string s = "6.3-full-day-care";
int index = s.IndexOf('-'); //This gets index of first '-' character
var price = s.Substring(0, index);
var serviceKey = s.Substring(index + 1);
Console.WriteLine(price);
Console.WriteLine(serviceKey);
Output will be;
6.3
full-day-care
Here a DEMO.

you can do like:
var val = "6.3-full-day-care";
var index = val.IndexOf("-"); //first occuarance of -
var price =double.Parse(val[index]);
var serviceKey = val.Substring(index);
Just to give idea. It's beter naturally use double.TryParse(..) on price
double price = 0;
double.TryParse(val[index], out prince, System.Globalization.InvariantCulture);

This should work
var s = "6.3-full-day-care";
var index = s.IndexOf('-');
var price = s.Substring(0, index);
var serviceKey = s.Substring(index + 1);

If the price and the key are always separated with a '-':
string s = "6.3-full-day-care";
int separatorIdx = s.IndexOf( '-' ); // get idx of first '-'
// split original string
string price = s.Substring( 0, separatorIdx );
string serviceKey = s.Substring( separatorIdx+1, s.Length );

Use String.Split with a maximum count http://msdn.microsoft.com/en-us/library/c1bs0eda.aspx
string s = "6.3-full-day-care";
string[] parts = s.split(new char[]{'-'}, 1);
var price = parts[0];
var serviceKey = parts[1];

Related

how to show number of digits on users's request?

for example: if a string value is "123456.7890" .
if user enters the length 6 and the other value 2 for the decimal place.
the output value should be like "123456.78"
if user enters the length 5 and the other value 3 for the decimal place.
the output value should be like "12345.789"
string s = "123456.7890";
string a = string.Format("{0, 2:F2}", s);
int index = a.IndexOf('.');
a = a.Substring(index, (a.Length-index));
One approach could be like this:
NOTE: If the string's length is less than the number of characters you're taking, code will throw an exception ArgumentOutOfRangeException
int LeftPlaces = 4;
int RightPlaces = 2;
String Input = "123456.7890";
String[] Splitted = Input.Split('.');
String StrLeft = Splitted[0].Substring(0, LeftPlaces);
String StrRight = Splitted[1].Substring(0, RightPlaces);
Console.WriteLine(StrLeft + "." + StrRight);
Output: 1234.78
The most crude and direct way would be:
var length = 5;
var decimalPlaces = 2;
var s = "123456.7890";
var data = s.Split('.');
var output1 = data[0].Substring(0, length);
var output2 = data[1].Substring(0, decimalPlaces);
var result = output1 + "." + output2;
If you want to do this without strings, you can do so.
public decimal TrimmedValue(decimal value,int iLength,int dLength)
{
var powers = Enumerable.Range(0,10).Select(x=> (decimal)(Math.Pow(10,x))).ToArray();
int iPart = (int)value;
decimal dPart = value - iPart;
var dActualLength = BitConverter.GetBytes(decimal.GetBits(value)[3])[2];
var iActualLength = (int)Math.Floor(Math.Log10(iPart) + 1);
if(dLength > dActualLength || iLength > iActualLength)
throw new ArgumentOutOfRangeException();
dPart = Math.Truncate(dPart*powers[dLength]);
iPart = (int)(iPart/powers[iActualLength - iLength]);
return iPart + (dPart/powers[dLength]);
}
Client Call
Console.WriteLine($"Number:123456.7890,iLength=5,dLength=3,Value = {TrimmedValue(123456.7890m,5,3)}");
Console.WriteLine($"Number:123456.7890,iLength=6,dLength=2,Value = {TrimmedValue(123456.7890m,6,2)}");
Console.WriteLine($"Number:123456.7890,iLength=2,dLength=4,Value = {TrimmedValue(123456.7890m,2,4)}");
Console.WriteLine($"Number:123456.7890,iLength=7,dLength=3,Value = {TrimmedValue(123456.7890m,7,3)}");
Output
Number:123456.7890,iLength=5,dLength=3,Value = 12345.789
Number:123456.7890,iLength=6,dLength=2,Value = 123456.78
Number:123456.7890,iLength=2,dLength=4,Value = 12.789
Last call would raise "ArgumentOutOfRangeException" Exception as the length is more than the actual value

Increment count in c#

I am trying to create a query. Here is the code
string wherequery = "";
int fromcode = Convert.ToInt32(CodeTextBox.Text);
int count = Convert.ToInt32(CountTextBox.Text);
for (int i = 0; i < count; i++)
wherequery += ("'" + (fromcode + i).ToString().PadLeft(8,'0') + "',");
wherequery = wherequery.TrimEnd(",");
I am using for loop to create a IN query. Is it possible via LINQ?
Output should be
'0000000087','0000000088','0000000089'
Second thing, I get the code from a textbox value like 0000000087. When I convert it into int using Convert.ToInt32, preceding 0s get disappeared.
Is it possible that 0s shouldn't get disappear since number of preceding 0s may vary?
No need for .PadLeft(8,'0') which causes unnecessary leading zeros.
Try following.
var whereQueryFormat = "Whre columnName IN ({0})";
var wherequery = string.Join
(",",
Enumerable.Range(1, count)
.Select(i => "'" + fromcode + i + "'")
);
wherequery = string.Format(whereQueryFormat, wherequery);
I am not quite sure if you can use LINQ at this point. Here is an example how I would solve this problem:
Dim whereQuery As String = ""
Dim operatorValues As New List(Of String)
Dim startingNumber As String = CodeTextBox.Text
Dim lengthOfNumber As Integer = startingNumber.Length
Dim count As Integer = Convert.ToInt32(CountTextBox.text)
For i As Integer = CInt(startingNumber) To CInt(startingNumber + count - 1)
operatorValues.Add(i.ToString.PadLeft(lengthOfNumber, "0"))
Next
whereQuery &= "IN ('" & Join(operatorValues.ToArray, "','") & "')"
Anyway: Why is your database-field a string and not a integer? Then you would not have a problem with the leading zeros.
If you want to remove the for operation, you could probably do it this way using LINQ, Enumerable.Range, and string.Join:
int fromcode = Convert.ToInt32(CodeTextBox.Text);
int count = Convert.ToInt32(CountTextBox.Text);
var words = from i in Enumerable.Range(fromcode, count)
select "'" + i.ToString().PadLeft(8, '0') + "'";
string wherequery = string.Join(",", words);
You will still have to use a loop for this. But the below code address your variable padded zeros issue.
var enteredValue = "00000088";//get this from the text box
int enteredCount = 10;//get this from the text box
string wherequery = "";
int fromCode = Convert.ToInt32(enteredValue);
string fromCodeStr = fromCode.ToString(CultureInfo.CurrentCulture);
string padZeros = enteredValue.Split(new[] {fromCodeStr}, StringSplitOptions.None)[0];
List<string> searchList = new List<string>();
for (int i = 1; i <= enteredCount; i++)
{
searchList.Add(padZeros + fromCode + i);
}
var searchString = string.Join(",", searchList);
If you want to use LINQ to get the IN clause you can use this:
var range = Enumerable.Range(0, count).Select(x =>
string.Format("'{0}'", x.ToString("0000000000")));
var inCluase = string.Format(" IN ({0})", string.Join(",", range));

get only integer value from string

I need to get only the last number from the string. The string contains pattern of string+integer+string+integer i.e. "GS190PA47". I need to get only 47 from the string.
Thank you
A simple regular expression chained to the end of the string for any number of integer digits
string test = "GS190PA47";
Regex r = new Regex(#"\d+$");
var m = r.Match(test);
if(m.Success == false)
Console.WriteLine("Ending digits not found");
else
Console.WriteLine(m.ToString());
string input = "GS190PA47";
var x = Int32.Parse(Regex.Matches(input, #"\d+").Cast<Match>().Last().Value);
If string always ends with number, you can simply use \d+$ pattern, as Steve suggests.
you can try this regex:
(\d+)(?!.*\d)
you can test it with this online tool: link
Try this:
string input = "GS190PA47";
Regex r = new Regex(#"\d+\D+(\d+)");
int number = int.Parse(r.Match(input).Groups[1].Value);
Pattern means we find set of digits (190), next set of non-digit chars (PA) and finally sought-for number.
Don't forget include using System.Text.RegularExpressions directive.
Not sure if this is less or more efficient than RegEx (Profile it)
string input = "GS190PA47";
var x = Int32.Parse(new string(input.Where(Char.IsDigit).ToArray()));
Edit:
Amazingly it is actually much faster than regex
var a = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
{
string input = "GS190PA47";
var x = Int32.Parse(new string(input.Reverse().TakeWhile(Char.IsDigit).Reverse().ToArray()));
}
a.Stop();
var b = a.ElapsedMilliseconds;
Console.WriteLine(b);
a = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
{
string input = "GS190PA47";
var x = Int32.Parse(Regex.Matches(input, #"\d+").Cast<Match>().Last().Value);
}
a.Stop();
b = a.ElapsedMilliseconds;
Console.WriteLine(b);

Masking all characters of a string except for the last n characters

I want to know how can I replace a character of a string with condition of "except last number characters"?
Example:
string = "4111111111111111";
And I want to make it that
new_string = "XXXXXXXXXXXXX1111"
In this example I replace the character to "X" except the last 4 characters.
How can I possibly achieve this?
Would that suit you?
var input = "4111111111111111";
var length = input.Length;
var result = new String('X', length - 4) + input.Substring(length - 4);
Console.WriteLine(result);
// Ouput: XXXXXXXXXXXX1111
How about something like...
new_string = new String('X', YourString.Length - 4)
+ YourString.Substring(YourString.Length - 4);
create a new string based on the length of the current string -4 and just have it all "X"s. Then add on the last 4 characters of the original string
Here's a way to think through it. Call the last number characters to leave n:
How many characters will be replaced by X? The length of the string minus n.
How can we replace characters with other characters? You can't directly modify a string, but you can build a new one.
How to get the last n characters from the original string? There's a couple ways to do this, but the simplest is probably Substring, which allows us to grab part of a string by specifying the starting point and optionally the ending point.
So it would look something like this (where n is the number of characters to leave from the original, and str is the original string - string can't be the name of your variable because it's a reserved keyword):
// 2. Start with a blank string
var new_string = "";
// 1. Replace first Length - n characters with X
for (var i = 0; i < str.Length - n; i++)
new_string += "X";
// 3. Add in the last n characters from original string.
new_string += str.Substring(str.Length - n);
This might be a little Overkill for your ask. But here is a quick extension method that does this.
it defaults to using x as the masking Char but can be changed with an optional char
public static class Masking
{
public static string MaskAllButLast(this string input, int charsToDisplay, char maskingChar = 'x')
{
int charsToMask = input.Length - charsToDisplay;
return charsToMask > 0 ? $"{new string(maskingChar, charsToMask)}{input.Substring(charsToMask)}" : input;
}
}
Here a unit tests to prove it works
using Xunit;
namespace Tests
{
public class MaskingTest
{
[Theory]
[InlineData("ThisIsATest", 4, 'x', "xxxxxxxTest")]
[InlineData("Test", 4, null, "Test")]
[InlineData("ThisIsATest", 4, '*', "*******Test")]
[InlineData("Test", 16, 'x', "Test")]
[InlineData("Test", 0, 'y', "yyyy")]
public void Testing_Masking(string input, int charToDisplay, char maskingChar, string expected)
{
//Act
string actual = input.MaskAllButLast(charToDisplay, maskingChar);
//Assert
Assert.Equal(expected, actual);
}
}
}
StringBuilder sb = new StringBuilder();
Char[] stringChar = string.toCharArray();
for(int x = 0; x < stringChar.length-4; x++){
sb.append(stringChar[x]);
}
sb.append(string.substring(string.length()-4));
string = sb.toString();
I guess you could use Select with index
string input = "4111111111111111";
string new_string = new string(input.Select((c, i) => i < input.Length - 4 ? 'X' : c).ToArray());
Some of the other concise answers here did not account for strings less than n characters. Here's my take:
var length = input.Length;
input = length > 4 ? new String('*', length - 4) + input.Substring(length - 4) : input;
lui,
Please Try this one...
string dispString = DisplayString("4111111111111111", 4);
Create One function with pass original string and no of digit.
public string DisplayString(string strOriginal,int lastDigit)
{
string strResult = new String('X', strOriginal.Length - lastDigit) + strOriginal.Substring(strOriginal.Length - lastDigit);
return strResult;
}
May be help you....
Try this:
String maskedString = "...."+ (testString.substring(testString.length() - 4, testString.length()));
Late to the party but I also wanted to mask all but the last 'x' characters, but only mask numbers or letters so that any - ( ), other formatting, etc would still be shown. Here's my quick extension method that does this - hopefully it helps someone. I started with the example from Luke Hammer, then changed the guts to fit my needs.
public static string MaskOnlyChars(this string input, int charsToDisplay, char maskingChar = 'x')
{
StringBuilder sbOutput = new StringBuilder();
int intMaskCount = input.Length - charsToDisplay;
if (intMaskCount > 0) //only mask if string is longer than requested unmasked chars
{
for (var intloop = 0; intloop < input.Length; intloop++)
{
char charCurr = Char.Parse(input.Substring(intloop, 1));
byte[] charByte = Encoding.ASCII.GetBytes(charCurr.ToString());
int intCurrAscii = charByte[0];
if (intloop <= (intMaskCount - 1))
{
switch (intCurrAscii)
{
case int n when (n >= 48 && n <= 57):
//0-9
sbOutput.Append(maskingChar);
break;
case int n when (n >= 65 && n <= 90):
//A-Z
sbOutput.Append(maskingChar);
break;
case int n when (n >= 97 && n <= 122):
//a-z
sbOutput.Append(maskingChar);
break;
default:
//Leave other characters unmasked
sbOutput.Append(charCurr);
break;
}
}
else
{
//Characters at end to remain unmasked
sbOutput.Append(charCurr);
}
}
}
else
{
//if not enough characters to mask, show unaltered input
return input;
}
return sbOutput.ToString();
}

Adding numbers to a string?

I have strings that look like "01", "02". Is there an easy way that I can change the string into a number, add 1 and then change it back to a string so that these strings now look like "02", "03" etc. I'm not really good at C# as I just started and I have not had to get values before.
To get from a string to an integer, you can youse int.Parse():
int i = int.Parse("07");
To get back into a string with a specific format you can use string.Format():
strings = string.Format("{0:00}",7);
The latter should give "07" if I understand http://www.csharp-examples.net/string-format-int/ correctly.
You can convert the string into a number using Convert.ToInt32(), add 1, and use ToString() to convert it back.
int number = Convert.ToInt32(originalString);
number += 1;
string newString = number.ToString();
Parse the integer
int i = int.Parse("07");
add to your integer
i = i + 1;
make a new string variable and assign it to the string value of that integer
string newstring = i.ToString();
AddStringAndInt(string strNumber, int intNumber)
{
//TODO: Add error handling here
return string.Format("{0:00}", (int.TryParse(strNumber) + intNumber));
}
static string StringsADD(string s1, string s2)
{
int l1 = s1.Count();
int l2 = s2.Count();
int[] l3 = { l1, l2 };
int minlength = l3.Min();
int maxlength = l3.Max();
int komsu = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < maxlength; i++)
{
Int32 e1 = Convert.ToInt32(s1.PadLeft(maxlength, '0').ElementAt(maxlength - 1 - i).ToString());
Int32 e2 = Convert.ToInt32(s2.PadLeft(maxlength, '0').ElementAt(maxlength - 1 - i).ToString());
Int32 sum = e1 + e2 + komsu;
if (sum >= 10)
{
sb.Append(sum - 10);
komsu = 1;
}
else
{
sb.Append(sum);
komsu = 0;
}
if (i == maxlength - 1 && komsu == 1)
{
sb.Append("1");
}
}
return new string(sb.ToString().Reverse().ToArray());
}
I needed to add huge numbers that are 1000 digit. The biggest number type in C# is double and it can only contain up to 39 digits. Here a code sample for adding very huge numbers treating them as strings.

Categories