How to find how many string in other string - c#

I randomly trying to make this code works. The problem that I have is I can't find the string in some string, because char only takes one character.
Is there another way to do it?
e.g. I can find how many char "e" in "excellent", But I can't find "ll". It'll give me error.
The code which I use:
try
{
int count = label1.Text.Split(Convert.ToChar(textBox1.Text)).Length - 1;
MessageBox.Show(count.ToString());
}
catch
{
messagebox.show("error");
}
Thats why I am using try to catch the error.

This is because you use Convert.ToChar(...) which is supposed to take only convertible string to char (that is, consists of a single character, but "ll" consists of two characters).
You could create an extension for string to do what you want:
public static class StringExtensions {
public static List<int> AllIndexesOf(this string str, string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
List<int> indexes = new List<int>();
for (int index = 0; ; index += value.Length) {
index = str.IndexOf(value, index);
if (index == -1)
return indexes;
indexes.Add(index);
}
}
}
And then just use it like:
int count = label1.Text.AllIndexesOf(textBox1.Text).Count;

Related

Method that takes a message and index, creates a substring using the index

Problem: I want to write a method that takes a message/index pair like this:
("Hello, I am *Name1, how are you doing *Name2?", 2)
The index refers to the asterisk delimited name in the message. So if the index is 1, it should refer to *Name1, if it's 2 it should refer to *Name2.
The method should return just the name with the asterisk (*Name2).
I have attempted to play around with substrings, taking the first delimited * and ending when we reach a character that isn't a letter, number, underscore or hyphen, but the logic just isn't setting in.
I know this is similar to a few problems on SO but I can't find anything this specific. Any help is appreciated.
This is what's left of my very vague attempt so far. Based on this thread:
public string GetIndexedNames(string message, int index)
{
int strStart = message.IndexOf("#") + "#".Length;
int strEnd = message.LastIndexOf(" ");
String result = message.Substring(strStart, strEnd - strStart);
}
If you want to do it the old school way, then something like:
public static void Main(string[] args)
{
string message = "Hello, I am *Name1, how are you doing *Name2?";
string name1 = GetIndexedNames(message, "*", 1);
string name2 = GetIndexedNames(message, "*", 2);
Console.WriteLine(message);
Console.WriteLine(name1);
Console.WriteLine(name2);
Console.ReadLine();
}
public static string GetIndexedNames(string message, string singleCharDelimiter, int index)
{
string valid = "abcdefghijlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-";
string[] parts = message.Split(singleCharDelimiter.ToArray());
if (parts.Length >= index)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < parts[index].Length; i++)
{
string character = parts[index].Substring(i, 1);
if (valid.Contains(character))
{
sb.Append(character);
}
else
{
return sb.ToString();
}
}
return sb.ToString();
}
return "";
}
You can try using regular expressions to match the names. Assuming that name is a sequence of word characters (letters or digits):
using System.Linq;
using System.Text.RegularExpressions;
...
// Either name with asterisk *Name or null
// index is 1-based
private static ObtainName(string source, int index) => Regex
.Matches(source, #"\*\w+")
.Cast<Match>()
.Select(match => match.Value)
.Distinct() // in case the same name repeats several times
.ElementAtOrDefault(index - 1);
Demo:
string name = ObtainName(
"Hello, I am *Name1, how are you doing *Name2?", 2);
Console.Write(name);
Outcome:
*Name2
Perhaps not the most elegant solution, but if you want to use IndexOf, use a loop:
public static string GetIndexedNames(string message, int index, char marker='*')
{
int lastFound = 0;
for (int i = 0; i < index; i++) {
lastFound = message.IndexOf(marker, lastFound+1);
if (lastFound == -1) return null;
}
var space = message.IndexOf(' ', lastFound);
return space == -1 ? message.Substring(lastFound) : message.Substring(lastFound, space - lastFound);
}

How to extract value in between values using c#

I have been trying to extract some text in between and after some string.
The text is always different but the string to use by indexOf method is always same
Here is how the string Data looks Like.
4D534D3839373400000000000000000001000000
61705F6B6C6F672E6C737400000000000800E0AF0700F0AF01000000
73756D6D6172792E68746D6C000000000000C0AFFFFFD7AF01000000
703166316532336535652E68746D6C000000C0AFFFFFD7AF01000000
703266316532336535652E68746D6C000000C0AFFFFFD7AF01000000
6472616D2E6C7374000000000000000000000080FFFFFFBF01000000
6F63696D656D2E6C737400000000000000006008FF3F600801000000
72706D5F636F64652E6C73740000000000002000FFFF210001000000
72706D5F646174612E6C73740000000000002900FFFF290001000000
72706D5F6D73672E6C737400000000000800F8AF0750F8AF01000000
646174612E7374617200645BC07B718F11000000E01117
This value is always constant: 01000000
this is how it looks like when extracted:
4D534D38393734000000000000000000
61705F6B6C6F672E6C737400000000000800E0AF0700F0AF
73756D6D6172792E68746D6C000000000000C0AFFFFFD7AF
703166316532336535652E68746D6C000000C0AFFFFFD7AF
703266316532336535652E68746D6C000000C0AFFFFFD7AF
6472616D2E6C7374000000000000000000000080FFFFFFBF
6F63696D656D2E6C737400000000000000006008FF3F6008
72706D5F636F64652E6C73740000000000002000FFFF2100
72706D5F646174612E6C73740000000000002900FFFF2900
72706D5F6D73672E6C737400000000000800F8AF0750F8AF
646174612E7374617200645BC07B718F11000000E01117
And this is what I have tried so far I tried extracting indexes of all: 01000000
using this method:
public static List<int> AllIndexesOf(this string str, string value)
{
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
List<int> indexes = new List<int>();
for (int index = 0; ; index += value.Length)
{
index = str.IndexOf(value, index);
if (index == -1)
return indexes;
indexes.Add(index);
}
}
How can I loop through all indexes and get the desired data.
Thanks
There's no need to do this manually using IndexOf, you can simply split the string based on the string:
var s = "4D534D3.....";
var results = s.Split(new[] {"01000000"}, StringSplitOptions.RemoveEmptyEntries);

take the last n lines of a string c#

I have a string of unknown length
it is in the format
\nline
\nline
\nline
with out know how long it is how can i just take the last 10 lines of the string
a line being separated by "\n"
As the string gets larger, it becomes more important to avoid processing characters that don't matter. Any approach using string.Split is inefficient, as the whole string will have to be processed. An efficient solution will have to run through the string from the back. Here's a regular expression approach.
Note that it returns a List<string>, because the results need to be reversed before they're returned (hence the use of the Insert method)
private static List<string> TakeLastLines(string text, int count)
{
List<string> lines = new List<string>();
Match match = Regex.Match(text, "^.*$", RegexOptions.Multiline | RegexOptions.RightToLeft);
while (match.Success && lines.Count < count)
{
lines.Insert(0, match.Value);
match = match.NextMatch();
}
return lines;
}
var result = text.Split('\n').Reverse().Take(10).ToArray();
Split() the string on \n, and take the last 10 elements of the resulting array.
If this is in a file and the file is particularly large, you may want to do this efficiently. A way to do it is to read the file backwards, and then only take the first 10 lines. You can see an example of using Jon Skeet's MiscUtil library to do this here.
var lines = new ReverseLineReader(filename);
var last = lines.Take(10);
Here's one way to do it that has the advantage that it doesn't create copies of the entire source string so is fairly efficient. Most of the code would be placed in a class along with other general purpose extension methods so the end result is that you can do it with 1 line of code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string x = "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\ng\r\nh\r\ni\r\nj\r\nk\r\nl\r\nm\r\nn\r\no\r\np";
foreach(var line in x.SplitAsEnumerable("\r\n").TakeLast(10))
Console.WriteLine(line);
Console.ReadKey();
}
}
static class LinqExtensions
{
public static IEnumerable<string> SplitAsEnumerable(this string source)
{
return SplitAsEnumerable(source, ",");
}
public static IEnumerable<string> SplitAsEnumerable(this string source, string seperator)
{
return SplitAsEnumerable(source, seperator, false);
}
public static IEnumerable<string> SplitAsEnumerable(this string source, string seperator, bool returnSeperator)
{
if (!string.IsNullOrEmpty(source))
{
int pos = 0;
do
{
int newPos = source.IndexOf(seperator, pos, StringComparison.InvariantCultureIgnoreCase);
if (newPos == -1)
{
yield return source.Substring(pos);
break;
}
yield return source.Substring(pos, newPos - pos);
if (returnSeperator) yield return source.Substring(newPos, seperator.Length);
pos = newPos + seperator.Length;
} while (true);
}
}
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int count)
{
List<T> items = new List<T>();
foreach (var item in source)
{
items.Add(item);
if (items.Count > count) items.RemoveAt(0);
}
return items;
}
}
}
EDIT: It has been pointed out that this could be more efficient because it iterates the entire string. I also think that RemoveAt(0) with a list is probably inefficient also. To resolve this the code could be modified to search through the string backwards. This would eliminate the need for the TakeLast function as we could just use Take.
space efficient approach
private static void PrintLastNLines(string str, int n)
{
int idx = str.Length - 1;
int newLineCount = 0;
while (newLineCount < n)
{
if (str[idx] == 'n' && str[idx - 1] == '\\')
{
newLineCount++;
idx--;
}
idx--;
}
PrintFromIndex(str, idx + 3);
}
private static void PrintFromIndex(string str, int idx)
{
for (int i = idx; i < str.Length; i++)
{
if (i < str.Length - 1 && str[i] == '\\' && str[i + 1] == 'n')
{
Console.WriteLine();
i++;
}
else
{
Console.Write(str[i]);
}
}
Console.WriteLine();
}

Replacing a char at a given index in string? [duplicate]

This question already has answers here:
how do I set a character at an index in a string in c#?
(7 answers)
Closed 5 years ago.
String does not have ReplaceAt(), and I'm tumbling a bit on how to make a decent function that does what I need. I suppose the CPU cost is high, but the string sizes are small so it's all ok
Use a StringBuilder:
StringBuilder sb = new StringBuilder(theString);
sb[index] = newChar;
theString = sb.ToString();
The simplest approach would be something like:
public static string ReplaceAt(this string input, int index, char newChar)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
char[] chars = input.ToCharArray();
chars[index] = newChar;
return new string(chars);
}
This is now an extension method so you can use:
var foo = "hello".ReplaceAt(2, 'x');
Console.WriteLine(foo); // hexlo
It would be nice to think of some way that only required a single copy of the data to be made rather than the two here, but I'm not sure of any way of doing that. It's possible that this would do it:
public static string ReplaceAt(this string input, int index, char newChar)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
StringBuilder builder = new StringBuilder(input);
builder[index] = newChar;
return builder.ToString();
}
... I suspect it entirely depends on which version of the framework you're using.
string s = "ihj";
char[] array = s.ToCharArray();
array[1] = 'p';
s = new string(array);
Strings are immutable objects, so you can't replace a given character in the string.
What you can do is you can create a new string with the given character replaced.
But if you are to create a new string, why not use a StringBuilder:
string s = "abc";
StringBuilder sb = new StringBuilder(s);
sb[1] = 'x';
string newS = sb.ToString();
//newS = "axc";
I suddenly needed to do this task and found this topic.
So, this is my linq-style variant:
public static class Extensions
{
public static string ReplaceAt(this string value, int index, char newchar)
{
if (value.Length <= index)
return value;
else
return string.Concat(value.Select((c, i) => i == index ? newchar : c));
}
}
and then, for example:
string instr = "Replace$dollar";
string outstr = instr.ReplaceAt(7, ' ');
In the end I needed to utilize .Net Framework 2, so I use a StringBuilder class variant though.
If your project (.csproj) allow unsafe code probably this is the faster solution:
namespace System
{
public static class StringExt
{
public static unsafe void ReplaceAt(this string source, int index, char value)
{
if (source == null)
throw new ArgumentNullException("source");
if (index < 0 || index >= source.Length)
throw new IndexOutOfRangeException("invalid index value");
fixed (char* ptr = source)
{
ptr[index] = value;
}
}
}
}
You may use it as extension method of String objects.
public string ReplaceChar(string sourceString, char newChar, int charIndex)
{
try
{
// if the sourceString exists
if (!String.IsNullOrEmpty(sourceString))
{
// verify the lenght is in range
if (charIndex < sourceString.Length)
{
// Get the oldChar
char oldChar = sourceString[charIndex];
// Replace out the char ***WARNING - THIS CODE IS WRONG - it replaces ALL occurrences of oldChar in string!!!***
sourceString.Replace(oldChar, newChar);
}
}
}
catch (Exception error)
{
// for debugging only
string err = error.ToString();
}
// return value
return sourceString;
}

Remove characters before character "."

How effectively remove all character in string that placed before character "."?
Input:
Amerika.USA
Output:
USA
You can use the IndexOf method and the Substring method like so:
string output = input.Substring(input.IndexOf('.') + 1);
The above doesn't have error handling, so if a period doesn't exist in the input string, it will present problems.
You could try this:
string input = "lala.bla";
output = input.Split('.').Last();
string input = "America.USA"
string output = input.Substring(input.IndexOf('.') + 1);
String input = ....;
int index = input.IndexOf('.');
if(index >= 0)
{
return input.Substring(index + 1);
}
This will return the new word.
Extension methods I commonly use to solve this problem:
public static string RemoveAfter(this string value, string character)
{
int index = value.IndexOf(character);
if (index > 0)
{
value = value.Substring(0, index);
}
return value;
}
public static string RemoveBefore(this string value, string character)
{
int index = value.IndexOf(character);
if (index > 0)
{
value = value.Substring(index + 1);
}
return value;
}
public string RemoveCharactersBeforeDot(string s)
{
string splitted=s.Split('.');
return splitted[splitted.Length-1]
}
A couple of methods that, if the char does not exists, return the original string.
This one cuts the string after the first occurrence of the pivot:
public static string truncateStringAfterChar(string input, char pivot){
int index = input.IndexOf(pivot);
if(index >= 0) {
return input.Substring(index + 1);
}
return input;
}
This one instead cuts the string after the last occurrence of the pivot:
public static string truncateStringAfterLastChar(string input, char pivot){
return input.Split(pivot).Last();
}

Categories

Resources