C# -Take a string between a text - c#

I've got various string in a list:
Ord.cl. N. 2724 del 08/11/2019
and it can be also
Ord.cl. N. 2725/web del 08/11/2019
I have to take all the content that comes after 'N.' and before 'del'. As result I want
2724
2725/web
Can someone do code for that in C#? I know there is substring, but maybe there are better ways?

you can build some extention method like this
public string SubstringFromTo(this string input, int from, int to)
{
return input.Substring(from, (to - from));
}
public string SubstringFromTo(this string input, string from, string to)
{
var index1 = input.IndexOf(from) != -1 ? input.IndexOf(from) : 0;
var index2 = input.IndexOf(to) != -1 ? input.IndexOf(to) : (input.Length - 1);
return input.SubstringFromTo(index1, index2);
}
var asd = " ciao ** come stai ? asdasd".SubstringFromTo("**","?");
result = "come stai"
//.Trim() if you want

Using regular expressions, you might do:
var m = Regex.Match("Ord.cl. N. 2724 del 08/11/2019", #"(?<=N\.).*?(?=del)");
if (m.Success)
{
var result = m.Value;
}
Explanation of the regular expression:
(?<=N\.) looks for a preceding "N.".
.*? matches any sequence of characters, but as few as possible
(?=del) lools for a trailng "del".

If it's always that predictable (space before and after N. and space before and after del), then it's fairly simple. Use Substring and use IndexOf to find the occurrences of N. and del:
var theString = "Ord.cl. N. 2725/web del 08/11/2019";
var start = theString.IndexOf("N. ") + 3;
var length = theString.IndexOf(" del", start) - start;
var partIWant = theString.Substring(start, length).Trim();
Console.WriteLine(partIWant);
That also assumes that there will only ever be one occurrence of N. and del in your string.

for (int i = 0; i< list.Count-1; i++)
{
NDocList.Add(list[i].DocumentiOrigine.Split(new string[] { " N. " }, StringSplitOptions.None)[1]
.Split()[0]
.Trim());
}
solved with this somehow.

Related

count the number of points at the end of a string

I need to count the number of points at the END of string.
The number of points in the middle of the string are not relevant and should not be countet.
How can this be done?
string sample = "This.is.a.sample.string.....";
for the example above the correct answer would be 5 because there are 5 points at the end of the string.
because of performace reasons I would prefer a fast solution. Don't know if Regular Expressions
\.*$
should be used in such a case.
Start from the end of the string and go back char by char until its not a dot:
string sample = "This.is.a.sample.string....."
int count = 0;
for (int i = sample.Length - 1; i >= 0; i--)
{
if (sample[i] != '.') break;
count++;
}
Using Linq:
var test = "this.is.a.test........";
var count = test.ToCharArray().Reverse().TakeWhile(q => q == '.').Count();
Convert string to array, reverse, then take while character = '.'. Count result.
A simple solution using an extension method.
var test = "this.is.a.test........";
Console.WriteLine(test.CountTrailingDots());
public static int CountTrailingDots(this string value)
{
return value.Length - value.TrimEnd('.').Length;
}
Using Regex:
int points = Regex.Match("This.is.a.sample.string....", #"^[\w\W]*?([.]*+)$").Groups[1].Value.Length;
Description:
*+ = Matches as many characters as possible
*? = Matches as few characters as possible.
It can be something like..
string sample = "This.is.a.sample.string.....";
int count = 0;
if(sample.EndsWith("."))
count = sample.Substring(sample.TrimEnd('.').Length).Length;

How to remove all but the first occurences of a character from a string?

I have a string of text and want to ensure that it contains at most one single occurrence of a specific character (,). Therefore I want to keep the first one, but simply remove all further occurrences of that character.
How could I do this the most elegant way using C#?
This works, but not the most elegant for sure :-)
string a = "12,34,56,789";
int pos = 1 + a.IndexOf(',');
return a.Substring(0, pos) + a.Substring(pos).Replace(",", string.Empty);
You could use a counter variable and a StringBuilder to create the new string efficiently:
var sb = new StringBuilder(text.Length);
int maxCount = 1;
int currentCount = 0;
char specialChar = ',';
foreach(char c in text)
if(c != specialChar || ++currentCount <= maxCount)
sb.Append(c);
text = sb.ToString();
This approach is not the shortest but it's efficient and you can specify the char-count to keep.
Here's a more "elegant" way using LINQ:
int commasFound = 0; int maxCommas = 1;
text = new string(text.Where(c => c != ',' || ++commasFound <= maxCommas).ToArray());
I don't like it because it requires to modify a variable from a query, so it's causing a side-effect.
Regular expressions are elegant, right?
Regex.Replace("Eats, shoots, and leaves.", #"(?<=,.*),", "");
This replaces every comma, as long as there is a comma before it, with nothing.
(Actually, it's probably not elegant - it may only be one line of code, but it may also be O(n^2)...)
If you don't deal with large strings and you reaaaaaaly like Linq oneliners:
public static string KeepFirstOccurence (this string #string, char #char)
{
var index = #string.IndexOf(#char);
return String.Concat(String.Concat(#string.TakeWhile(x => #string.IndexOf(x) < index + 1)), String.Concat(#string.SkipWhile(x=>#string.IndexOf(x) < index)).Replace(#char.ToString(), ""));
}
You could write a function like the following one that would split the string into two sections based on the location of what you were searching (via the String.Split() method) for and it would only remove matches from the second section (using String.Replace()) :
public static string RemoveAllButFirst(string s, string stuffToRemove)
{
// Check if the stuff to replace exists and if not, return the original string
var locationOfStuff = s.IndexOf(stuffToRemove);
if (locationOfStuff < 0)
{
return s;
}
// Calculate where to pull the first string from and then replace the rest of the string
var splitLocation = locationOfStuff + stuffToRemove.Length;
return s.Substring(0, splitLocation) + (s.Substring(splitLocation)).Replace(stuffToRemove,"");
}
You could simply call it by using :
var output = RemoveAllButFirst(input,",");
A prettier approach might actually involve building an extension method that handled this a bit more cleanly :
public static class StringExtensions
{
public static string RemoveAllButFirst(this string s, string stuffToRemove)
{
// Check if the stuff to replace exists and if not, return the
// original string
var locationOfStuff = s.IndexOf(stuffToRemove);
if (locationOfStuff < 0)
{
return s;
}
// Calculate where to pull the first string from and then replace the rest of the string
var splitLocation = locationOfStuff + stuffToRemove.Length;
return s.Substring(0, splitLocation) + (s.Substring(splitLocation)).Replace(stuffToRemove,"");
}
}
which would be called via :
var output = input.RemoveAllButFirst(",");
You can see a working example of it here.
static string KeepFirstOccurance(this string str, char c)
{
int charposition = str.IndexOf(c);
return str.Substring(0, charposition + 1) +
str.Substring(charposition, str.Length - charposition)
.Replace(c, ' ').Trim();
}
Pretty short with Linq; split string into chars, keep distinct set and join back to a string.
text = string.Join("", text.Select(c => c).Distinct());

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++);
}

Find the exact occurence of a string in HTML file

I would like to find the count of Exact match of string
Let suppose string is 'My Computer'. I want to find it,s occurrence in string
This is My computer,this is a good Computer,this is my Computer,this is my Computers
So at end I shall get Count 2 ,
I have tried the following formula with 'mykeyWord' as string to be found.
int strength = (innerDocument.DocumentNode.InnerText.Length - innerDocument.DocumentNode.InnerText.ToLower().Replace(mykeyWord.ToLower(), "").Length) / mykeyWord.Length;
But it will also count strings like 'my Computers' that is wrong.
This is a perfect place to use regular expressions, just as you tagged your post:
Regex re = new Regex("\\b" + Regex.Escape(mykeyWord) + "\\b", RegexOptions.IgnoreCase);
int count = re.Matches(innerDocument.DocumentNode.InnerText).Count;
You could use the regular expression [^A-z](my computer)[^A-z] This matches 'my computer' but not if it's before or after 'A to Z'. To make the regex search case insensitive use RegexOptions.IgnoreCase.
Edit
minitech's answer using word boundaries is better.
int FindCount(string keyword, string input)
{
if (input.Contains(keyword))
{
int count = 0;
int i = 0;
foreach (var c in input)
{
if (c == keyword[i])
i++;
else
i = 0;
if (i == keyword.Length)
{
i = 0;
count++;
}
}
return count;
}
return 0;
}

Getting parts of a string and combine them in C#?

I have a string like this: C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg
Now, what I want to do is to dynamically combine the last 4 numbers, in this case its 10000080 as result. My idea was ti split this and combine them in some way, is there an easier way? I cant rely on the array index, because the path can be longer or shorter as well.
Is there a nice way to do that?
Thanks :)
A compact way using string.Join and Regex.Split.
string text = #"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
string newString = string.Join(null, Regex.Split(text, #"[^\d]")); //10000080
Use String.Split
String toSplit = "C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
String[] parts = toSplit.Split(new String[] { #"\" });
String result = String.Empty;
for (int i = 5, i > 1; i--)
{
result += parts[parts.Length - i];
}
// Gives the result 10000080
You can rely on array index if the last part always is the filename.
since the last part is always
array_name[array_name.length - 1]
the 4 parts before that can be found by
array_name[array_name.length - 2]
array_name[array_name.length - 3]
etc
If you always want to combine the last four numbers, split the string (use \ as the separator), start counting from the last part and take 4 numbers, or the 4 almost last parts.
If you want to take all the digits, just scan the string from start to finish and copy just the digits to a new string.
string input = "C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
string[] parts = toSplit.Split(new char[] {'\\'});
IEnumerable<string> reversed = parts.Reverse();
IEnumerable<string> selected = reversed.Skip(1).Take(4).Reverse();
string result = string.Concat(selected);
The idea is to extract the parts, reverse them to keep only the last 4 (excluding the file name) and re reversing to rollback to the initial order, then concat.
Using LINQ:
string path = #"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
var parts = Path.GetDirectoryName(path).Split('\\');
string numbersPart = parts.Skip(parts.Count() - 4)
.Aggregate((acc, next) => acc + next);
Result: "10000080"
var r = new Regex(#"[^\d+]");
var match = r
.Split(#"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg")
.Aggregate((i, j) => i + j);
return match.ToString();
to find the number you can use regex:
(([0-9]{2})\\){4}
use concat all inner Group ([0-9]{2}) to get your searched number.
This will always find your searched number in any position in the given string.
Sample Code:
static class TestClass {
static void Main(string[] args) {
string[] tests = { #"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg",
#"C:\Projects\test\whatever\files\media\10\00\00\80\some\foldertest.jpg",
#"C:\10\00\00\80\test.jpg",
#"C:\10\00\00\80\test.jpg"};
foreach (string test in tests) {
int number = ExtractNumber(test);
Console.WriteLine(number);
}
Console.ReadLine();
}
static int ExtractNumber(string path) {
Match match = Regex.Match(path, #"(([0-9]{2})\\){4}");
if (!match.Success) {
throw new Exception("The string does not contain the defined Number");
}
//get second group that is where the number is
Group #group = match.Groups[2];
//now concat all captures
StringBuilder builder = new StringBuilder();
foreach (var capture in #group.Captures) {
builder.Append(capture);
}
//pares it as string and off we go!
return int.Parse(builder.ToString());
}
}

Categories

Resources