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);
Related
The parameter is a string that has a number in each word. I need to search that word for the number. My solution so far is to split the string up into a string array, and use Array.IndexOf to find the matching index of my search. However I haven't been able to find a way to successfully use wildcards. Using string.Contains seems to work, but searching with Array.IndexOf doesn't.
How can I search a string array element for a word that contains a number and return it's index? 1-9.
public static string Order(string words)
{
string[] wordArr = words.Split(' ');
string[] wordsOrdered = new string[words.Length];
int k;
for (int i = 0, j = 1; i < wordsOrdered.Length; i++, j++)
{
if (words.Contains($"{j}"))
{
k = Array.IndexOf(wordArr, $"{j}");
if (k != -1)
wordsOrdered[i] = wordArr[k];
}
}
return words = wordsOrdered.ToString();
}
A Regular Expression that looks for the presence of digits in your words seems the most simple solution
public static string Order(string words)
{
string[] wordArr = words.Split(' ');
string[] wordsOrdered = new string[wordArr.Length];
Regex r = new Regex(#"\d+");
for (int i = 0; i < wordArr.Length; i++)
{
var m = r.Match(wordArr[i]);
if(m.Success)
{
int index = Convert.ToInt32(m.Value);
wordsOrdered[index-1] = wordArr[i];
}
}
return string.Join(" ", wordsOrdered);
}
This code assumes that all your words have at least one number internally and the lowest number start at 1. (A 0 will result in an index out of range exception) and also you shouldn't have numbers that are greater than then count of the input words.
I want to make a simple generator of strings.
User inputs a "template" for string. Template can have placeholders in any place in it.
Then he inputs possible characters that can fit into any placeholder in string.
How it should work:
INPUT:
a.b.
123
OUTPUT:
[
"a1b1", "a1b2", "a1b3",
"a2b1", "a2b2", "a2b3",
"a3b1", "a3b2", "a3b3"
]
I found some of my old python code, but i don't understand it at all.
I split the input string to array of strings and array of dots.
Then I tried to increment just dots and each time just concat those two arrays in the right way.
But I found a new trouble.
string[] splitted = kt_NonCur.Split('.'); // array of constant strings
char[] nch = new char[splitted.Length - 1]; // array of new chars (generated)
char lgc = goodLetters.Last( ); // last good char
for( int i = 0; i < nch.Length - 1; i++ ) // set up all nch to first letter
nch[i] = goodLetters[0];
while( nch.Last( ) != lgc ) { // until last nch is set to last good char
outputData.Add($"{concatsplit(splitted, nch)}"); // concatsplit(s,n) concatenates two arrays into string
nch[0] = up(nch[0]); // up(char) gets next character from goodLetters. If there is no next, it returns first letter.
if( nch[0] == goodLetters[0] ) {
nch[1] = up(nch[1]);
if(nch[1] == goodLetters[0]){
nch[2] = up(nch[2]);
// .
// .
// .
}
}
}
And the problem is: I am facing a dilemma. Either find better way, or limit number of placeholders so that the code ladder is not too long. Of course I would add then some code that checks if it is the last and stop executing code for others, but I still would have to make
You can look at your problem this way: if you have P placeholders in your input string and the number of replacement characters is R, to construct every possibe output string you need at each step P numbers [0...R-1] (which can then serve as index into the replacement character list). Well, this is the definition of an integer with P digits in base R.
So let's write a helper class representing such integers:
class NDigitNumber
{
int[] _digits;
int _base;
// construct an integer with the specified numer of digits in the specified base
public NDigitNumber(int digits, int #base)
{
_digits = new int[digits];
_base = #base;
}
// get the digit at the specified position
public int this[int index] => _digits[index];
// increment the number, returns false on overflow
public bool Increment()
{
for (var pos = 0; pos < _digits.Length; pos++)
{
if (++_digits[pos] < _base)
break;
if (pos == _digits.Length-1)
return false;
for (var i = 0; i <= pos; i++)
_digits[i] = 0;
}
return true;
}
}
The Increment methods works like these mechanical counter devices where each digit wheel, when rotated from its maximum digit to the next, resets itself and all lower wheels to 0 and increments the next higher wheel.
Then we only have to iterate over all possible such integers to get the desired output:
var input = "a.b.";
var placeholder = '.';
var replacements = new[] { '1', '2', '3' };
// determine positions of placeholder in string
var placeholderPositions = new List<int>();
for (var i = 0; i < input.Length; i++)
{
if (input[i] == placeholder)
placeholderPositions.Add(i);
}
// iterate over all possible integers with
// placeholderPositions.Count digits
// in base replacements.Length
var number = new NDigitNumber(placeholderPositions.Count, replacements.Length);
do
{
var result = new StringBuilder(input);
for (var i = 0; i < placeholderPositions.Count; i++)
result[placeholderPositions[i]] = replacements[number[i]];
Console.WriteLine(result.ToString());
} while(number.Increment());
Output:
a1b1
a2b1
a3b1
a1b2
a2b2
a3b2
a1b3
a2b3
a3b3
Based on accepted answer of this post:
public static IEnumerable<string> Combinations(string template, string str, char placeholder)
{
int firstPlaceHolder = template.IndexOf(placeholder);
if (firstPlaceHolder == -1)
return new string[] { template };
string prefix = template.Substring(0, firstPlaceHolder);
string suffix = template.Substring(firstPlaceHolder + 1);
var recursiveCombinations = Combinations(suffix, str, placeholder);
return
from chr in str
from recSuffix in recursiveCombinations
select prefix + chr + recSuffix;
}
Usage:
List<string> combinations = Combinations("a.b.", "123", '.').ToList();
I need to parse this string
"+CMGL: 1,\"REC READ\",\"+420731177370\",\"\",\"2015/03/21 11:26:10+04\""
and I would like to parse for
id = 1, number = +420731177370, date = 2015/03/21 11:26:10+04\
Could you please help me how to do it without Regex because I have got an old version of micro framework.
My code is
for (int i = 0; i < sentences.Length; i += 2)
{
string[] test = sentences[i].Split(',');
for (int j = 1; j < test.Length; j++)
{
//to do stuff
}
}
to do stuff where i need to replace \"xxxxx\" to xxxx
Perhaps something like this will point you in the right direction. Just be aware that while the code below works well for the string in your original post, should that string change it might not work as well since it's relying on character counts as opposed to regexes.
var Source = "+CMGL: 1,\"REC READ\",\"+420731177370\",\"\",\"2015/03/21 11:26:10+04\"";
var SplitSource = Source.Split(',');
String ID = SplitSource[0].ToString().Remove(0, 6); //good
String Number = SplitSource[2].Replace("\"", ""); //good
String Date = SplitSource[4].Replace("\"", ""); //good
for (int i = 0; i < links.Count; i++)
{
int f = links[i].IndexOf("http");
}
links is List<string>
For example in index 0 I have: http://test/107281.shtml#34
I want to extract from this link only this:
http://test/107281.shtml without the #34 in the end.
But for the start why f return 0 all the time ?
It's right...., cause this string "http" start index is 0, if couldn't found string, IndexOf will return -1...
The first char in a string is located at index 0, so in the string http://test/107281.shtml#34 as http is the first thing in the string its located at index 0...
To extract you can use either regex or indexOf("#") in combination with substring.
The indexOf() method returns the position of the first occurrence of a specified value in a string.
var str = "Hello world, welcome to the universe.";
var n = str.indexOf("welcome");
Output wil be : 13
which is the position number.
Next you remove from which position you want to delete.
I guess you are looking for something like:
for (int i = 0; i < links.Count; i++)
{
int f = links[i].IndexOf("#");
}
This should give you the index of the first #.
IndexOf("http") should give you 0 as http is at index 0.
To get the string you are seeking:
for (int i = 0; i < links.Count; i++)
{
var url = links[i].Substring(0, links[i].IndexOf("#"));
}
Example using your demo string HERE.
List<string> link_list = new List<string> { "http://test/107281.shtml#34", "http://test/107281.shtml#35" };
List<string> new_list = new List<string>();
foreach (var item in link_list)
{
string bb = item.Substring(0, item.ToString().IndexOf("#"));
new_list.Add(bb);
}
If you take a look at the plastic in your wallet the 16 digit credit card number is broken into 4 groups of 4. Im trying to do the same thing,
Currently I have a string that has 16 digits but is formed as 1 single number. How can I add a " " after the 4th 8th & 12th number?
Any tips would be really helpful.
Thanks
var number = 1234567890123456;
number.ToString( "0000-0000-0000-0000" );
Try something similar to this answer, using a NumberFormatInfo:
NumberFormatInfo format = new NumberFormatInfo();
format.NumberGroupSeparator = " ";
format.NumberGroupSizes = new[] { 4 };
format.NumberDecimalDigits = 0;
Use as:
long number = 7314787188619939;
string formatted = number.ToString("n", format);
Console.WriteLine(formatted);
Or, if you're dealing with a string, you may choose can use a regex for a quick string manipulation. This will be easy to adapt to other characters:
string str = "7314787188619939";
str = Regex.Replace(str, "(?!^).{4}", " $0" ,RegexOptions.RightToLeft);
string number = "1234567890ABCDEF";
int counter = 0;
var result = number
.GroupBy(_ => counter++ / 4)
.Select(g => new String(g.ToArray()));
There are many answers. Given a string s=1234567890123456 the easiest might be to create a StringBuilder and append it. Untested code example below.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; i += 4)
{
sb.append(s.Substring(i, 4)); // Append these 4
if (i != s.Length - 4)
sb.append(" "); // append a space for all but the last group
}
Console.WriteLine(sb.ToString());
You may try something like this, an extension method
public static IEnumerable<String> SplitToParts(this String forSplit, Int32 splitLength)
{
for (var i = 0; i < forSplit.Length; i += splitLength)
yield return forSplit.Substring(i, Math.Min(splitLength, forSplit.Length - i));
}
string s ="1234123412341234";
s.SplitToParts(4) should do the trick
Hope this works !
Or if working with MD5 hashes, you could use an implementation like so...
public string exHashMd5(string data)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(data));
byte[] result = md5.Hash;
StringBuilder str = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
str.Append(result[i].ToString("X2"));
}
/// The implementation like so. (Below)
NumberFormatInfo format = new NumberFormatInfo();
format.NumberGroupSeparator = " ";
format.NumberGroupSizes = new[] { 8 };
format.NumberDecimalDigits = 0;
string rstr = str.ToString();
rstr = Regex.Replace(rstr, "(?!^).{8}", " $0", RegexOptions.RightToLeft);
return rstr.ToString();
/// At the end you get yourself a nice 4 way split.
/// Test it out. have a go with chucking it into a
/// MessageBox.Show(exHashMd5("yourstring"));
}
/// Could even go one further and add
string hashtext;
string newline = Enviroment.Newline;
hashtext = exHashMd5("yourtext");
/// Then you do a simple command.
MessageBox.Show(hashtext + newline + hashtext);
/// Nice four way again. complex but yet made simple.
To work out what you need it to do, use maths. seriously, its mathematical. divide the amount of characters, till you are able to get a sum that equals four. for example, 32 / 8 = 4. then this will give you the four way split you need. basic maths. basic. basic. basic.