How to replace a particular character from string in c#? - c#

I have a string like AX_1234X_12345_X_CXY, I want to remove X from after the first underscore _ i.e. from 1234X to 1234. So final output will be like AX_1234_12345_X_CXY. How to do it?? If I use .Replace("X", "") it will replace all X which I don't want

You can iterate trough the string from the first occurrence of '_' .
you can find the first occurrence of '_' using IndexOf().
when loop will get to 'X' it will not append it to the "fixed string".
private static void Func()
{
string Original = "AX_1234X_12345_X_CXY";
string Fixed = Original.Substring(0, Original.IndexOf("_", 0));
// in case you want to remove all 'X`s' after first occurrence of `'_'`
// just dont use that variable
bool found = false;
for (int i = Original.IndexOf("_", 0); i < Original.Length; i++)
{
if (Original[i].ToString()=="X" && found == false)
{
found = true;
}
else
{
Fixed += Original[i];
}
}
Console.WriteLine(Fixed);
Console.ReadLine();
}

Why not good old IndexOf and Substring?
string s = "AX_1234X_12345_X_CXY";
int pUnder = s.IndexOf('_');
if (pUnder >= 0) { // we have underscope...
int pX = s.IndexOf('X', pUnder + 1); // we should search for X after the underscope
if (pX >= 0) // ...as well as X after the underscope
s = s.Substring(0, pX) + s.Substring(pX + 1);
}
Console.Write(s);
Outcome:
AX_1234_12345_X_CXY

string original = #"AX_1234X_12345_X_CXY";
original = #"AX_1234_12345_X_CXY";

One way is String.Remove, because you can tell exactly where to remove from. If the offending "X" is always in the same place, you can use:
string newString = old.Remove(7,1);
This will remove 1 character starting as position 7 (counting from zero as the beginning of the string).
If not always in the same character position, you might try:
int xPos = old.IndexOf("X");
string newString = old.Remove(xPos,1);
EDIT:
Based on OP comment, the "X" we're targeting occurs just after the first underscore character, so let's index off of the first underscore:
int iPosUnderscore = old.IndexOf("_");
string newString = old.Remove(iPosUnderscore + 1 ,1); // start after the underscore

Try looking at string.IndexOf or string.IndexOfAny
string s = "AX_1234X_12345_X_CXY";
string ns = HappyChap(s);
public string HappyChap(string value)
{
int start = value.IndexOf("X_");
int next = start;
next = value.IndexOf("X_", start + 1);
if (next > 0)
{
value = value.Remove(next, 1);
}
return value;
}

If and only if this is always the format then it should be a simple matter of combining substrings of the original text without including the x in that position. But the op hasn't stated that this is always the case. So if this is always the format and the same character position is always removed then you could simply just
string s = "AX_1234X_12345_X_CXY";
string newstring = s.Substring(0, 7) + s.Substring(8);
OK, based on only the second set of numbers being variable in length, you could then do something like:
int startpos = s.IndexOf('_', 4);
string newstring = s.Substring(0, startpos - 1) + s.Substring(startpos);
with this code, the following tests resulted in:
"AX_1234X_12345_X_CXY" became "AX_1234_12345_X_CXY"
"AX_123X_12345_X_CXY" became "AX_123_12345_X_CXY"
"AX_234X_12345_X_CXY" became "AX_234_12345_X_CXY"
"AX_1X_12345_X_CXY" became "AX_1_12345_X_CXY"

Something like this could work. I'm sure there's a more elegant solution.
string input1 = "AX_1234X_12345_X_CXY";
string pattern1 = "^[A-Z]{1,2}_[0-9]{1,4}(X)";
string newInput = string.Empty;
Match match = Regex.Match(input1, pattern1);
if(match.Success){
newInput = input1.Remove(match.Groups[1].Index, 1);
}
Console.WriteLine(newInput);

Related

Given a string find occurrences and replace with another string without using string.replace()

Here is an example of what I want to implement: for instance, given the string Something, if you were to replace all occurrences of so with DDD, the result would be DDDmething.
Here is how I am implementing it; my code finds a char by its specific position and changes it, but in fact I want to implement what I stated above.
static void Main(string[] args)
{
string str = "The Haunting of Hill House!";
Console.WriteLine("String: " + str);
// replacing character at position 7
int pos = 7;
char rep = 'p';
string res = str.Substring(0, pos) + rep + str.Substring(pos + 1);
Console.WriteLine("String after replacing a character: " + result);
Console.ReadLine();
}
Alternative might be to split the string by "so" and join the resulting array by "DDD" :
string result = string.Join("DDD", "something".Split(new[] { "so" }, StringSplitOptions.None));
This should do what you want. The idea is to use IndexOf to find the index of the substring to replace then append the substring before it followed by the replacement, then start the search over from the end of the found substring. Then after all substrings are found and replaced append the rest of the original string to the end if there is any.
Note this doesn't do any checks on the input and you really should use the string.Replace as I'm sure it's more performant.
public string Replace(string input, string find, string replace)
{
// The current index in the string where we are searching from
int currIndex = 0;
// The index of the next substring to replace
int index = input.IndexOf(find);
// A string builder used to build the new string
var builder = new StringBuilder();
// Continue until the substring is not found
while(index != -1)
{
// If the current index is not equal to the substring location
// when we need to append everything from the current position
// to where we found the substring
if(index != currIndex )
{
builder.Append(input.Substring(currIndex , index - currIndex));
}
// Now append the replacement
builder.Append(replace);
// Move the current position past the found substring
currIndex = index + find.Length;
// Search for the next substring.
index = input.IndexOf(find, currIndex );
}
// If the current position is not the end of the string we need
// to append the remainder of the string.
if(currIndex < input.Length)
{
builder.Append(input.Substring(currIndex));
}
return builder.ToString();
}
You could do it like this:
var someString = "This is some sort of string.";
var resultIndex = 0;
var searchKey ="So";
var replacementString = "DDD";
while ((resultIndex = someString.IndexOf(searchKey, resultIndex, StringComparison.OrdinalIgnoreCase)) != -1)
{
var prefix = someString.Substring(0, Math.Max(0, resultIndex - 1));
var suffix = someString.Substring(resultIndex + searchKey.Length);
someString = prefix + replacementString + suffix;
resultIndex += searchKey.Length;
}
Expected to produce "This is DDDme DDDrt of string.".

C#: Increment only the last number of a String

I have strings that look like this:
1.23.4.34
12.4.67
127.3.2.21.3
1.1.1.9
This is supposed to be a collection of numbers, separated by '.' symbols, similar to an ip address. I need to increment only the last digit/digits.
Expected Output:
1.23.4.35
12.4.68
127.3.2.21.4
1.1.1.10
Basically, increment whatever the number that is after the last '.' symbol.
I tried this:
char last = numberString[numberString.Length - 1];
int number = Convert.ToInt32(last);
number = number + 1;
If I go with the above code, I just need to replace the characters after the last '.' symbol with the new number. How do I get this done, good folks? :)
It seems to me that one method would be to:
split the string on . to get an array of components.
turn the final component into an integer.
increment that integer.
turn it back into a string.
recombine the components with . characters.
See, for example, the following program:
using System;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
String original = "1.23.4.34";
String[] components = original.Split('.');
int value = Int32.Parse(components[components.Length - 1]) + 1;
components[components.Length - 1] = value.ToString();
String newstring = String.Join(".",components);
Console.WriteLine(newstring);
}
}
}
which outputs the "next highest" value of:
1.23.4.35
You can use string.LastIndexOf().
string input = "127.3.2.21.4";
int lastIndex = input.LastIndexOf('.');
string lastNumber = input.Substring(lastIndex + 1);
string increment = (int.Parse(lastNumber) + 1).ToString();
string result = string.Concat(input.Substring(0, lastIndex + 1), increment);
You need to extract more than just the last character. What if the last character is a 9 and then you add 1 to it? Then you need to correctly add one to the preceding character as well. For example, the string 5.29 should be processed to become 5.30 and not simply 5.210 or 5.20.
So I suggest you split the string into its number sections. Parse the last section into an integer. Increment it and then create the string again. I leave it as an exercise for the poster to actually write the few lines of code. Good practice!
Something like this:
var ip = "1.23.4.34";
var last = int.Parse(ip.Split(".".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries).Last());
last = last + 1;
ip = string.Format("{0}.{1}",ip.Remove(ip.LastIndexOf(".")) , last);
If you are dealing with IP, there will be some extra code in case of .034, which should be 035 instead of 35. But that logic is not that complicated.
It's simple as this, use Split() and Join() String methods
String test = "1.23.4.34"; // test string
String[] splits = test.Split('.'); // split by .
splits[splits.Length - 1] = (int.Parse(splits[splits.Length - 1])+1).ToString(); // Increment last integer (Note : Assume all are integers)
String answ = String.Join(".",splits); // Use string join to make the string from string array. uses . separator
Console.WriteLine(answ); // Answer : 1.23.4.35
Using a bit of Linq
int[] int_arr = numberString.Split('.').Select(num => Convert.ToInt32(num)).ToArray();
int_arr[int_arr.Length - 1]++;
numberString = "";
for(int i = 0; i < int_arr.Length; i++) {
if( i == int_arr.Length - 1) {
numberString += int_arr[i].ToString();
}
else {
numberString += (int_arr[i].ToString() + ".");
}
}
Note: on phone so can't test.
My Solution is:
private static string calcNextCode(string value, int index)
{
if (value is null) return "1";
if (value.Length == index + 1) return value + "1";
int lastNum;
int myIndex = value.Length - ++index;
char myValue = value[myIndex];
if (int.TryParse(myValue.ToString(), NumberStyles.Integer, null, out lastNum))
{
var aStringBuilder = new StringBuilder(value);
if (lastNum == 9)
{
lastNum = 0;
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return calcNextCode(aStringBuilder.ToString(), index++);
}
else
{
lastNum++;
}
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return aStringBuilder.ToString();
}
return calcNextCode(value, index++);
}

Im trying to use indexof and substring to extract text from a file but the variable index is -1 all the time what is wrong?

I have a html file with some strings inside for example:
"http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150000&cultuur=en-GB&continent=europa","http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150300&cultuur=en-GB&continent=europa","http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150600&cultuur=en-GB&continent=europa"
I ant to extract each line: http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150000&cultuur=en-GB&continent=europa
Then the next one: http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150300&cultuur=en-GB&continent=europa
This is the code im using:
In the constructor i did:
f = File.ReadAllText(localFilename + "test.html");
retrivingText1();
private void retrivingText1()
{
string startTag = "http://www.niederschlagsradar.de/images.aspx";//"<Translation>";
string endTag = "continent=europa";//"</Translation>";
int startTagWidth = startTag.Length;
int endTagWidth = endTag.Length;
index = 0;
w = new StreamWriter(#"d:\retrivedText1.txt");
while (true)
{
index = f.IndexOf(startTag, index);
if (index == -1)
{
break;
}
// else more to do - index now is positioned at first character of startTag
int start = index + startTagWidth;
index = f.LastIndexOf(endTag, start + 1);
if (index == -1)
{
break;
}
// found the endTag
string g = f.Substring(start, index - start + endTagWidth).Trim(); //Trim the founded text so the start and ending spaces are removed.
w.WriteLine(g);
//break so you dont have an endless loop
break;
}
w.Close();
}
I know for extracting from html file its better to use htmlagilitypack or regex. But i wanted to try this time indexof and substring.
When i use a breakpoint so on the line:
int start = index + startTagWidth;
start = 2950
The next line after it index = -1
I prefer Don's answer, but if you really want to use indexof it is much easier if you prime the loop and do something like this:
private void button3_Click(object sender, EventArgs e)
{
string f = "\"http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150000&cultuur=en-GB&continent=europa\",\"http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150300&cultuur=en-GB&continent=europa\",\"http://www.niederschlagsradar.de/images.aspx?jaar=-6&type=europa.precip&datum=201309150600&cultuur=en-GB&continent=europa\"";
int startIndex = 0;
int endIndex = 0;
int position = 0;
string startTag = "http://www.niederschlagsradar.de/images.aspx";//"<Translation>";
string endTag = "continent=europa";//"</Translation>";
startIndex = f.IndexOf(startTag);
while (startIndex > 0)
{
endIndex = f.IndexOf(endTag, position);
//parse out what you want
position = endIndex + endTag.Length;
startIndex = (f.IndexOf(startTag, position));
//something here to prevent endless loop
}
}
On the Page you refer to I cannot find the lines of text that you are looking for...
I think, like you also thought about, that it would be alot better using a regular expression:
http:\/\/www\.niederschlagsradar\.de\/images\.aspx\?jaar=-6&type=europa\.precip&datum=\d{12}&cultuur=en-GB&continent=europa
Then you will get all the references you need for further processing.
EDIT
If you wan't to use IndexOf and SubString. You are using the LastIndexOf in the wrong way. LastIndexOf is seaching backwards in the string toward the beginning of the string.
Documentation
Try to just use IndexOf instead
Given your example file, I would prefer:
String[] sa = f.Split(',');
foreach (String s in sa)
{
String strToWrite = f.Trim('\"');
//write your string
}

How to make a first letter capital in C#

How can the first letter in a text be set to capital?
Example:
it is a text. = It is a text.
public static string ToUpperFirstLetter(this string source)
{
if (string.IsNullOrEmpty(source))
return string.Empty;
// convert to char array of the string
char[] letters = source.ToCharArray();
// upper case the first char
letters[0] = char.ToUpper(letters[0]);
// return the array made of the new char array
return new string(letters);
}
It'll be something like this:
// precondition: before must not be an empty string
String after = before.Substring(0, 1).ToUpper() + before.Substring(1);
polygenelubricants' answer is fine for most cases, but you potentially need to think about cultural issues. Do you want this capitalized in a culture-invariant way, in the current culture, or a specific culture? It can make a big difference in Turkey, for example. So you may want to consider:
CultureInfo culture = ...;
text = char.ToUpper(text[0], culture) + text.Substring(1);
or if you prefer methods on String:
CultureInfo culture = ...;
text = text.Substring(0, 1).ToUpper(culture) + text.Substring(1);
where culture might be CultureInfo.InvariantCulture, or the current culture etc.
For more on this problem, see the Turkey Test.
If you are using C# then try this code:
Microsoft.VisualBasic.StrConv(sourceString, Microsoft.VisualBasic.vbProperCase)
I use this variant:
private string FirstLetterCapital(string str)
{
return Char.ToUpper(str[0]) + str.Remove(0, 1);
}
If you are sure that str variable is valid (never an empty-string or null), try:
str = Char.ToUpper(str[0]) + str[1..];
Unlike the other solutions that use Substring, this one does not do additional string allocations. This example basically concatenates char with ReadOnlySpan<char>.
I realize this is an old post, but I recently had this problem and solved it with the following method.
private string capSentences(string str)
{
string s = "";
if (str[str.Length - 1] == '.')
str = str.Remove(str.Length - 1, 1);
char[] delim = { '.' };
string[] tokens = str.Split(delim);
for (int i = 0; i < tokens.Length; i++)
{
tokens[i] = tokens[i].Trim();
tokens[i] = char.ToUpper(tokens[i][0]) + tokens[i].Substring(1);
s += tokens[i] + ". ";
}
return s;
}
In the sample below clicking on the button executes this simple code outBox.Text = capSentences(inBox.Text.Trim()); which pulls the text from the upper box and puts it in the lower box after the above method runs on it.
Take the first letter out of the word and then extract it to the other string.
strFirstLetter = strWord.Substring(0, 1).ToUpper();
strFullWord = strFirstLetter + strWord.Substring(1);
text = new String(
new [] { char.ToUpper(text.First()) }
.Concat(text.Skip(1))
.ToArray()
);
this functions makes capital the first letter of all words in a string
public static string FormatSentence(string source)
{
var words = source.Split(' ').Select(t => t.ToCharArray()).ToList();
words.ForEach(t =>
{
for (int i = 0; i < t.Length; i++)
{
t[i] = i.Equals(0) ? char.ToUpper(t[i]) : char.ToLower(t[i]);
}
});
return string.Join(" ", words.Select(t => new string(t)));;
}
string str = "it is a text";
// first use the .Trim() method to get rid of all the unnecessary space at the begining and the end for exemple (" This string ".Trim() is gonna output "This string").
str = str.Trim();
char theFirstLetter = str[0]; // this line is to take the first letter of the string at index 0.
theFirstLetter.ToUpper(); // .ToTupper() methode to uppercase the firstletter.
str = theFirstLetter + str.substring(1); // we add the first letter that we uppercased and add the rest of the string by using the str.substring(1) (str.substring(1) to skip the first letter at index 0 and only print the letters from the index 1 to the last index.)
Console.WriteLine(str); // now it should output "It is a text"
static String UppercaseWords(String BadName)
{
String FullName = "";
if (BadName != null)
{
String[] FullBadName = BadName.Split(' ');
foreach (string Name in FullBadName)
{
String SmallName = "";
if (Name.Length > 1)
{
SmallName = char.ToUpper(Name[0]) + Name.Substring(1).ToLower();
}
else
{
SmallName = Name.ToUpper();
}
FullName = FullName + " " + SmallName;
}
}
FullName = FullName.Trim();
FullName = FullName.TrimEnd();
FullName = FullName.TrimStart();
return FullName;
}
string Input = " it is my text";
Input = Input.TrimStart();
//Create a char array
char[] Letters = Input.ToCharArray();
//Make first letter a capital one
string First = char.ToUpper(Letters[0]).ToString();
//Concatenate
string Output = string.Concat(First,Input.Substring(1));
Try this code snippet:
char nm[] = "this is a test";
if(char.IsLower(nm[0])) nm[0] = char.ToUpper(nm[0]);
//print result: This is a test

c# getting a string within another string

i have a string like this:
some_string = "A simple demo of SMS text messaging.\r\n+CMGW: 3216\r\n\r\nOK\r\n\"
im coming from vb.net and i need to know in c#, if i know the position of CMGW, how do i get "3216" out of there?
i know that my start should be the position of CMGW + 6, but how do i make it stop as soon as it finds "\r" ??
again, my end result should be 3216
thank you!
Find the index of \r from the start of where you're interested in, and use the Substring overload which takes a length:
// Production code: add validation here.
// (Check for each index being -1, meaning "not found")
int cmgwIndex = text.IndexOf("CMGW: ");
// Just a helper variable; makes the code below slightly prettier
int startIndex = cmgwIndex + 6;
int crIndex = text.IndexOf("\r", startIndex);
string middlePart = text.Substring(startIndex, crIndex - startIndex);
If you know the position of 3216 then you can just do the following
string inner = some_string.SubString(positionOfCmgw+6,4);
This code will take the substring of some_string starting at the given position and only taking 4 characters.
If you want to be more general you could do the following
int start = positionOfCmgw+6;
int endIndex = some_string.IndexOf('\r', start);
int length = endIndex - start;
string inner = some_string.SubString(start, length);
One option would be to start from your known index and read characters until you hit a non-numeric value. Not the most robust solution, but it will work if you know your input's always going to look like this (i.e., no decimal points or other non-numeric characters within the numeric part of the string).
Something like this:
public static int GetNumberAtIndex(this string text, int index)
{
if (index < 0 || index >= text.Length)
throw new ArgumentOutOfRangeException("index");
var sb = new StringBuilder();
for (int i = index; i < text.Length; ++i)
{
char c = text[i];
if (!char.IsDigit(c))
break;
sb.Append(c);
}
if (sb.Length > 0)
return int.Parse(sb.ToString());
else
throw new ArgumentException("Unable to read number at the specified index.");
}
Usage in your case would look like:
string some_string = #"A simple demo of SMS text messaging.\r\n+CMGW: 3216\r\n...";
int index = some_string.IndexOf("CMGW") + 6;
int value = some_string.GetNumberAtIndex(index);
Console.WriteLine(value);
Output:
3216
If you're looking to extract the number portion of 'CMGW: 3216' then a more reliable method would be to use regular expressions. That way you can look for the entire pattern, and not just the header.
var some_string = "A simple demo of SMS text messaging.\r\n+CMGW: 3216\r\n\r\nOK\r\n";
var match = Regex.Match(some_string, #"CMGW\: (?<number>[0-9]+)", RegexOptions.Multiline);
var number = match.Groups["number"].Value;
More general, if you don't know the start position of CMGW but the structure remains as before.
String s;
char[] separators = {'\r'};
var parts = s.Split(separators);
parts.Where(part => part.Contains("CMGW")).Single().Reverse().TakeWhile(c => c != ' ').Reverse();

Categories

Resources