Move part of string to another string - c#

Maybe I don't have the right keywords but I can't seem to find how to do it.
Let's say I have these two string :
firstString = "I am a string";
secondString = "I am a long";
Is there a method that would allow me to move part of string 1 to string 2 ?
Move, not copy.
The final results would be :
firstString = "I am a"
secondString = "I am a long string"
The Problem
I have a string that contains a lot of characters. I want to send this string to SQLServer but the function that receives it can't hold more than 8000 char. So I need to send a request every 8000 characters.
Check if String1 is longer than 8000 Char
If it is, take the first 8000 Char and MOVE them into String2
Insert String2 into SQL
Repeat
If it's lenght is smaller than 8000 Char, send String 1 to SQL

Strings are immutable so what you are really doing is reassigning part of firstString to itself and assigning the other part concatenated to the end of secondString. There is no built in method to achieve this, but the code is pretty simple
secondString += firstString.Substring(6);
firstString = firstString.Substring(0,6);

Is there a method that would allow me to move part of string 1 to string 2 ? Move, not copy.
Since .NET strings are immutable, they cannot support methods with "move" semantic. Every modification of a string requires creation of a new object, entailing copying.
EDIT (in response to the edit of the question) It looks like your problem has to do with splitting the string at 8K characters, not necessarily moving parts of the string. In this case, you could use this simple code to pass parts of the string to SQL:
string string1 = GetReallyLongString();
const int sqlMax = 8000;
while (true) {
if (string1.Length > sqlMax) {
SendToSql(string1.Substring(0, sqlMax));
string1 = string1.Substring(sqlMax);
} else {
SendToSql(string1);
break;
}
}
Here is a quick demo on ideone.

As strings are immutable, you can't change them. You create new strings with parts from the original strings:
firstString = "I am a string";
secondString = "I am a long";
// concatenate second string with part from first string
secondSring = secondString + firstString.Substring(6);
// create a new string from part of the first string
firstString = firstString.Substring(0, 6);

Many ways to do that:
var partofstring = firstString.Substring(10, 14);
firstString = firstString.Replace(partofstring, "");
secondString += partofstring;

Inspired by dasblinkenlight's solution, but using yield to make a static method, and using as few substrings as possible to reduce memory usage.
using System;
using System.Collections.Generic;
public class Test
{
public static void Main()
{
string string1 = "quick brown fox jumps over the lazy dog";
foreach (var strSection in string1.SplitInto(8))
Console.WriteLine("'{0}'", strSection);
}
}
public static class MyExtensions
{
public static IEnumerable<string> SplitInto(this string value, int size)
{
for (int i = 0; i < value.Length; i += size)
{
if (i + size <= value.Length)
yield return value.Substring(i, size);
else
yield return value.Substring(i);
}
}
}
See it run at Ideone.

Related

PigLatin how can I strip punctuation from a string? And Then add it back?

Working on program for class call pig Latin. It works for what I need for class. It ask just to type in a phase to convert. But I notice if I type a sentence with punctuation at the end it will mess up the last word translation. Trying to figure out the best way to fix this. New at programming but I would need away for it to check last character in word to check for punctuations. Remove it before translation and then add it back. Not sure how to do that. Been reading about char.IsPunctuation. Plus not sure what part of my code I would had for that check.
public static string MakePigLatin(string str)
{
string[] words = str.Split(' ');
str = String.Empty;
for (int i = 0; i < words.Length; i++)
{
if (words[i].Length <= 1) continue;
string pigTrans = new String(words[i].ToCharArray());
pigTrans = pigTrans.Substring(1, pigTrans.Length - 1) + pigTrans.Substring(0, 1) + "ay ";
str += pigTrans;
}
return str.Trim();
}
The following should get you strings of letters for converting while passing through any non-letter characters that follow them.
Splitter based on Splitting a string in C#
public static string MakePigLatin(string str) {
MatchCollection matches = Regex.Matches(str, #"([a-zA-Z]*)([^a-zA-Z]*)");
StringBuilder result = new StringBuilder(str.Length * 2);
for (int i = 0; i < matches.Count; ++i) {
string pigTrans = matches[i].Groups[1].Captures[0].Value ?? string.Empty;
if (pigTrans.Length > 1) {
pigTrans = pigTrans.Substring(1) + pigTrans.Substring(0, 1) + "ay";
}
result.Append(pigTrans).Append(matches[i].Groups[2].Captures[0].Value);
}
return result.ToString();
}
The matches variable should contain all the match collections of 2 groups. The first group will be 0 or more letters to translate followed by a second group of 0 or more non-letters to pass through. The StringBuilder should be more memory efficient than concatenating System.String values. I gave it a starting allocation of double the initial string size just to avoid having to double the allocated space. If memory is tight, maybe 1.25 or 1.5 instead of 2 would be better, but you'd probably have to convert it back to int after. I took the length calculation off your Substring call because leaving it out grabs everything to the end of the string already.

How to delete the first 2 lines from string in C#?

I have a string like the following:
string myString = #"This is the first line
This is the third line as the 2nd is empty
The string continues
Anso so on ...
...
..
.";
I know that I can split this into an array, delete the first 2 elements and then rebuild my string from that array but I'm looking for something much more simple.
myString = String.Join("\n", myString.Split('\n').Skip(2));
Here's #maccettura's fiddle of that code with your string literal.
To break that down:
Split on newlines, return a sequence of segments -- the segments are lines, since we split on newline:
myString.Split('\n')
Skip the first two segments, return the rest of the a sequence
.Skip(2)
And rejoin the shorter sequence with newlines:
String.Join("\n", ...
This is just what you were contemplating doing in a loop, but with Skip(), it can be expressed as a readable one-liner.
Lastly, here's #user1242967 's version of the Split() call, which will handle \r\n newlines:
myString.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None)
If you do want to micro-optimize (or your strings are large, or you're calling this in a loop), here is a more performant way to do it:
private static string RemoveFirstTwoLines(string myString) {
int ix = myString.IndexOf('\n');
ix = myString.IndexOf('\n', ix + 1);
return myString.Substring(ix + 1);
}
Good for large strings, code easy to read:
using System.IO;
namespace ConsoleApplication
{
class Program
{
static void Main (string[] args)
{
var text = "line 1\r\nline 2\r\nline 3\r\nline 4";
using (var sr = new StringReader (text))
{
sr.ReadLine ();
sr.ReadLine ();
string result = sr.ReadToEnd ();
}
}
}
}

C# String Length returning the wrong amount

I have a string of 13 characters. 8C4B99823CB9C.
I am assigning it to a string.
string serialNumber = "‭8C4B99823CB9C‬";
This string then enters a method
GenerateCode(proxy, serialNumber, product);
Inside this method I have this line...
codeSerial = serial_no.Substring(serial_no.Length - codeSerialLength, codeSerialLength);
In the watch this is showing the length as 15.
Here is the full code
[TestMethod]
public void CanGenerateCodeNumberWithPrefixWithHEX()
{
string serialNumber = "‭8C4B99823CB9C‬";
Entity product = new Entity();
product.Attributes["piv_codeseriallength"] = 8;
product.Attributes["piv_codeprefix"] = "G";
string result = GenerateCode(proxy, serialNumber, product);
string expected = "G9823CB9C";
Assert.AreEqual(expected, result, "The Code was not generated correctly");
}
public static string GenerateCode(IOrganizationService _service, string serial_no, Entity product)
{
string codeSerial = null;
//Serial Length
if (product.Attributes.ContainsKey("piv_codeseriallength"))
{
codeSerial = serial_no;
int codeSerialLength = product.GetAttributeValue<int>("piv_codeseriallength");
codeSerial = serial_no.Substring(serial_no.Length - codeSerialLength, codeSerialLength);
string prefix = product.Attributes.ContainsKey("piv_codeprefix") ? product.GetAttributeValue<string>("piv_codeprefix") : "";
codeSerial = prefix + codeSerial;
}
return codeSerial;
}
This unit test fails because it thinks the string is 15 characters long and so taking the wrong section of the string
You have hidden unicode characters in your string. One good way to find out is to copy&paste the full string into a text editor, then try to move the caret left and right along the string. You'll see that you need to press left or right twice around the quotes, meaning that there's more characters then meet the eye. Of course, another way would be simply to open the string in a hexadecimal editor.
Assuming you only need simple characters, you can sanitize your input with a regex, to strip the extra characters:
var sanitizedInput = Regex.Replace(input, #"[^\w:/ ]", string.Empty);
In debug you can watch serialNumber.ToArray() you will notice that there is char 8237 at the begining of string and 8236 at the end

Cut off the end of a string

I need to figure out how to remove the end of a string. The only trouble is, the string itself is not set. All I want to keep is the first 3-4 characters in the string.
string Location = "110 - Main Road";
string Location = "123 - Highway";
string Location = "234 - My House";
It could also be;
string Location = "1120 - Main Road";
I know if I can cut it down to the first 4 characters, I can just use .Trim() to remove the white spaces if it is only 3 characters, but I don't know how to cut it down to the first 4 characters?
You can use Split and get your number like this:
string Location = "1120 - Main Road";
int number = int.Parse(Location.Split()[0]);
This should work if there is no white-space before the number.If there is then use StringSplitOptions.RemoveEmptyEntries:
int number = int.Parse(Location.Split(new []{ ' ' },
StringSplitOptions.RemoveEmptyEntries)[0]);
split on spaces, then grab whatever is first, ignore the rest.
string GrabNumber(string input)
{
return input.Split(' ')[0];
}
assuming you want it as an integer you can take it a step further:
int GrabNumber(string input)
{
return int.Parse(input.Split(' ')[0]);
}
You can use String.Split() function to split your string based on delimeter - and then you can convert the first part of the string into integer if you want it in a Integer variable.
Solution 1: if you want to get first part of string as as string.
string Location = "11056 - Main Road";
Location = Location.Split('-')[0].Trim();
Solution 2: if you want to get the first part of the string as integer value.
string Location = "11056 - Main Road";
int num;
int.TryParse(Location.Split('-')[0],out num);
Just use a Substring call with a String.IndexOf, for example
using System;
using System.Collections.Generic;
public class Test
{
public static void Main()
{
List<string> strings = new List<string>();
strings.Add("110 - Main Road");
strings.Add("1104 - Main Road");
strings.Add("11088 - Main Road");
foreach(string s in strings){
Console.WriteLine(s.Substring(0,s.IndexOf("-",0)-1));
}
}
}
That way even if the street number is 4,5,6,7 characters long this will still work
If you just want the first 4 characters you would do this:
Location = Location.Substring(0, 4);
The first argument is the start position and the second argument is the length.
use the substring function of string(startIndex,numberOfCharToKeep) like this:
string Location = "110 - Main Road";
string NewLocation = Location.SubString(0,4);
this keeps your first 4 chars
Depends on how reliable your input is. If you will always have a space after the numbers you can find that location using IndexOf. However, whenever I work with strings I prefer regular expressions. Here is an example of both approaches:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
string[] locations =
{
"110 - Main Road",
"123 - Highway",
"234 - My House",
"1120 - Main Road"
};
Regex r = new Regex(#"^\d+");
foreach (string location in locations)
{
Console.WriteLine(location.Substring(0, location.IndexOf(' ')));
Console.WriteLine(r.Match(location).Captures[0].Value);
}
}
}

C# Replacing part of string by start and end position

I have a string and I want to replace a part of it.
The tricky part is that that I can't use Regex.replace, because I only know the start and end positions of the data in the string.
For example, if the string looks like this:
I love cats, some more stuff here, we dont know how much more
And I have start=8 and end=11. And I want to replace that part to whatever I need to. This time lets say dogs so the new string will look like:
I love dogs, some more stuff here, we dont know how much more
How I could do that?
Simplest way:
string replaced = original.Substring(0, start) + replacementText +
original.Substring(end);
I had expected StringBuilder to have something which would do this, but I think you'd have to call Remove then Insert.
str.Substring(0, 8) + "replacement" + str.Substring(11);
It's not "elegant", but it works.
ReplaceAt(int index, int length, string replace)
Here's an extension method that doesn't use StringBuilder or Substring. This method also allows the replacement string to extend past the length of the source string.
//// str - the source string
//// index- the start location to replace at (0-based)
//// length - the number of characters to be removed before inserting
//// replace - the string that is replacing characters
public static string ReplaceAt(this string str, int index, int length, string replace)
{
return str.Remove(index, Math.Min(length, str.Length - index))
.Insert(index, replace);
}
When using this function, if you want the entire replacement string to replace as many characters as possible, then set length to the length of the replacement string:
"0123456789".ReplaceAt(7, 5, "Salut") = "0123456Salut"
Otherwise, you can specify the amount of characters that will be removed:
"0123456789".ReplaceAt(2, 2, "Salut") = "01Salut456789"
If you specify the length to be 0, then this function acts just like the insert function:
"0123456789".ReplaceAt(4, 0, "Salut") = "0123Salut456789"
I guess this is more efficient since the StringBuilder class need not be initialized and since it uses more basic operations.
Hope this help
string newString =
String.Concat(
originalString.Substring(0, start),
replacementText,
originalString.Substring(end));
OR
StringBuilder sb = new StringBuilder(originalString);
sb
.Remove(start, length)
.Insert(start, replacementText);
Not elegant but funny solution :
string myString = "I love cats, some more stuff here, we dont know how much more";
Regex expr = new Regex("cats");
int start = 8;
int end = 11;
Match m =expr.Match(myString);
if (m.Index == start-1 && m.Length == end - (start-1))
{
Console.WriteLine(expr.Replace(myString, "dogs"));
}
Just for fun with LINQ:
const string S = "I love cats, some more stuff here, we dont know how much more";
const string Dogs = "dogs";
var res = S
.Take(7)
.Concat(Dogs)
.Concat(S.Where((c, i) => i > 10));
var resultString = string.Concat(res);

Categories