I have a string that contains an int. How can I parse the int in C#?
Suppose I have the following strings, which contains an integer:
15 person
person 15
person15
15person
How can I track them, or return null if no integer is found in the string?
You can remove all non-digits, and parse the string if there is anything left:
str = Regex.Replace(str, "\D+", String.Empty);
if (str.Length > 0) {
int value = Int32.Parse(str);
// here you can use the value
}
Paste this code into a test:
public int? ParseAnInt(string s)
{
var match = System.Text.RegularExpressions.Regex.Match(s, #"\d+");
if (match.Success)
{
int result;
//still use TryParse to handle integer overflow
if (int.TryParse(match.Value, out result))
return result;
}
return null;
}
[TestMethod]
public void TestThis()
{
Assert.AreEqual(15, ParseAnInt("15 person"));
Assert.AreEqual(15, ParseAnInt("person 15"));
Assert.AreEqual(15, ParseAnInt("person15"));
Assert.AreEqual(15, ParseAnInt("15person"));
Assert.IsNull(ParseAnInt("nonumber"));
}
The method returns null is no number is found - it also handles the case where the number causes an integer overflow.
To reduce the chance of an overflow you could instead use long.TryParse
Equally if you anticipate multiple groups of digits, and you want to parse each group as a discreet number you could use Regex.Matches - which will return an enumerable of all the matches in the input string.
Use something like this :
Regex r = new Regex("\d+");
Match m = r.Match(yourinputstring);
if(m.Success)
{
Dosomethingwiththevalue(m.Value);
}
Since everyone uses Regex to extract the numbers, here's a Linq way to do it:
string input = "15person";
string numerics = new string(input.Where(Char.IsDigit).ToArray());
int result = int.Parse(numerics);
Just for the sake of completeness, it's probably not overly elegant. Regarding Jaymz' comment, this would return 151314 when 15per13so14n is passed.
Related
I want to know about how to splitting a value in string format in to two parts. Here in my asp application I'm parsing string value from view to controller.
And then I want to split the whole value in to two parts.
Example like: Most of the times value firest two letters could be TEXT value (like "PO" , "SS" , "GS" ) and the rest of the others are numbers (SS235452).
The length of the numbers cannot declare, since it generates randomly. So Want to split it from the begining of the string value. Need a help for that.
My current code is
string approvalnumber = approvalCheck.ApprovalNumber.ToUpper();
Thanks.
As you already mentioned that first part will have 2 letters and it's only second part which is varying, you can use Substring Method of String as shown below.
var textPart = input.Substring(0,2);
var numPart = input.Substring(2);
The first line fetches 2 characters from starting index zero and the second statement fetches all characters from index 2. You can cast the second part to a number if required.
Please note that the second parameter of Substring is not mentioned in second line. This parameter is for length and if nothing is mentioned it fetches till end of string.
You could try using regex to extract alpha, numbers from the string.
This javascript function returns only numbers from the input string.
function getNumbers(input) {
return input.match(/[0-9]+/g);
}
I'd use a RegExp. Considering the fact that you indicate ASP-NET-4 I assume you can't use tuples, out var etc. so it'd go as follows:
using System.Text.RegularExpressions;
using FluentAssertions;
using Xunit;
namespace Playground
{
public class Playground
{
public struct ProjectCodeMatch
{
public string Code { get; set; }
public int? Number { get; set; }
}
[Theory]
[InlineData("ABCDEFG123", "ABCDEFG", 123)]
[InlineData("123456", "", 123456)]
[InlineData("ABCDEFG", "ABCDEFG", null)]
[InlineData("ab123", "AB", 123)]
public void Split_Works(string input, string expectedCode, int? expectedNumber)
{
ProjectCodeMatch result;
var didParse = TryParse(input, out result);
didParse.Should().BeTrue();
result.Code.Should().Be(expectedCode);
result.Number.Should().Be(expectedNumber);
}
private static bool TryParse(string input, out ProjectCodeMatch result)
{
/*
* A word on this RegExp:
* ^ - the match must happen at the beginning of the string (nothing before that)
* (?<Code>[a-zA-Z]+) - grab any number of letters and name this part the "Code" group
* (?<Number>\d+) - grab any number of numbers and name this part the Number group
* {0,1} this group must occur at most 1 time
* $ - the match must end at the end of the string (nothing after that)
*/
var regex = new Regex(#"^(?<Code>[a-zA-Z]+){0,1}(?<Number>\d+){0,1}$");
var match = regex.Match(input);
if (!match.Success)
{
result = default;
return false;
}
int number;
var isNumber = int.TryParse(match.Groups["Number"].Value, out number);
result = new ProjectCodeMatch
{
Code = match.Groups["Code"].Value.ToUpper(),
Number = isNumber ? number : null
};
return true;
}
}
}
A linq answer:
string d = "PO1232131";
string.Join("",d.TakeWhile(a => Char.IsLetter(a)))
I want to extract the double from my string.
buff = "VA VV_CELL1 3.55"
When i use the following code
private void GetLine(string msg, string buff, double numb)
{
comPort.WriteLine(msg);
Thread.Sleep(50);
buff = comPort.ReadExisting();
Thread.Sleep(50);
MatchCollection matches = Regex.Matches(buff, #".*?([-]{0,1} *\d+.\d+)");
List<double> doubles = new List<double>();
foreach (Match match in matches)
{
string value = match.Groups[1].Value;
value = value.Replace(" ", "");
doubles.Add(double.Parse(value));
Thread.Sleep(200);
numb = doubles[0];
}
}
This code work for my other strings but "CELL1" contains a number so i dont get the wanted value "3.55" any ideas?
Why you don't simply split this string and take the last part?
string numberPart = buff.Split().Last();
double num;
bool validNum = double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out num);
Another way is to use Substring and LastIndexOf(which fails if there is no space):
string numberPart = buff.Substring(buff.LastIndexOf(' ')).Trim();
To help on your comment:
I'd use a method that returns a double?(double that can be null):
double? GetNumber(string buff)
{
string numberPart = buff.Split().Last();
double num;
bool validNum = double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out num);
if (validNum)
return num;
else
return null;
}
Now you can use the method and you even know whether the number could be parsed successfully or not:
double? result = GetNumber("VA VV_CELL1");
bool wasValid = result.HasValue;
if(wasValid)
{
double value = result.Value;
}
Try, this regex expression : \s+\d+(.)?\d+
I assume you want to capture both doubles and integers, otherwise you could write \d+\.\d+. This :
Regex.Matches("VA VV_CELL1 3.55",#"\d+\.\d+")[0]
Returns 3.55 but can't capture 355.
You can capture an integer or decimal preceded by whitespace with \s+\d+(\.\d+)?.
Regex.Matches("VA VV_CELL1 3.55",#"\s+\d+(\.\d+)?")[0]
Returns 3.55 while
Regex.Matches("VA VV_CELL1 355",#"\s+\d+(\.\d+)?")[0]
Returns 355
If you want to capture only the last field you can use \s+\d+(\.\d+)?$,eg:
Regex.Matches("VA VV_CELL1 3.54 3.55",#"\s+\d+(\.\d+)?$")[0]
Returns 3.55
You don't need to trim whitespace because double.Parse ignores it. You can change the pattern to capture the number in a separate group though, by surrounding the digits with parentheses :
Regex.Matches("VA VV_CELL1 3.54 3.55",#"\s+(\d+(\.\d+)?)$")[0].Groups[1]
You need to use Groups[1] because the first group always returns the entire capture
I need to determine if a string can be parsed into an array of int. The string MAY be in the format
"124,456,789,0"
In case which can it can converted thus:
int[] Ids = SearchTerm.Split(',').Select(int.Parse).ToArray();
However the string may also be something like:
"Here is a string, it is very nice."
In which case the parsing fails.
The logic currently branches in two directions based on whether the string contains a comma character (assuming that only the array-like strings will contain this character) but this logic is now flawed and comma characters are now appearing in other strings.
I could put a Try..Catch around it but I am generally adverse to controlling logic flow by exceptions.
Is there an easy way to do this?
I could put a Try..Catch around it but I am generally adverse to controlling logic flow by exceptions
Good attitude. If you can avoid the exception, do so.
A number of answers have suggested
int myint;
bool parseFailed = SearchTerm.Split(',')
.Any( s => !int.TryParse(s, out myint));
Which is not bad, but not great either. I would be inclined to first, write a better helper method:
static class Extensions
{
public static int? TryParseAsInteger(this string s)
{
int j;
bool success = int.TryParse(s, out j);
if (success)
return j;
else
return null;
}
}
Now you can say:
bool parseFailed = SearchTerm.Split(',')
.Any( s => s.TryParseAsInteger() == null);
But I assume that what you really want is the parsed state if it can succeed, rather than just answering the question "would a parse succeed?" With this helper method you can say:
List<int?> parse = SearchTerm.Split(',')
.Select( s => s.TryParseAsInteger() )
.ToList();
And now if the list contains any nulls, you know that it was bad; if it doesn't contain any nulls then you have the results you wanted:
int[] results = parse.Contains(null) ? null : parse.Select(x=>x.Value).ToArray();
int myint;
bool parseFailed = SearchTerm.Split(',')
.Any( s => !int.TryParse(s, out myint));
You can use multiline lambda expression to get int.TryParse for every Split method result:
var input = "124,456,789,0";
var parts = input.Split(new [] {","}, StringSplitOptions.RemoveEmptyEntries);
var numbers
= parts.Select(x =>
{
int v;
if (!int.TryParse(x, out v))
return (int?)null;
return (int?)v;
}).ToList();
if (numbers.Any(x => !x.HasValue))
Console.WriteLine("string cannot be parsed as int[]");
else
Console.WriteLine("OK");
It will not only check if value can be parsed to int, but also return the value if it can, so you don't have to do the parsing twice.
you can use RegEx to determine if the string match your pattern
something like this
string st = "124,456,789,0";
string pattS = #"[0-9](?:\d{0,2})";
Regex regex = new Regex(pattS);
var res = regex.Matches(st);
foreach (var re in res)
{
//your code here
}
tested on rubular.com here
How about,
int dummy;
var parsable = SearchTerm.Split(',').All(s => int.TryParse(s, out dummy));
but if you are doing that you might as well just catch the exception
Why dont you first remove the characters from the string and use
bool res = int.TryParse(text1, out num1);
Example below has no limit.
The BigInteger type is an immutable type that represents an arbitrarily large integer whose value in theory has no upper or lower bounds.
BigInteger MSDN
string test = "20,100,100,100,100,100,100";
test = test.Replace(",", "");
BigInteger num1 = 0;
bool res = BigInteger.TryParse(test, out num1);
I have string like this:
strings s = "1.0E-20"
Is there a way to get only -20 from this using regex?
I tried this:
(([1-9]+\.[0-9]*)|([1-9]*\.[0-9]+)|([1-9]+))([eE][-+]?[0-9]+)?
this gets me e-20 in group5 but still not just -20.
Use Regex for dealing with text, use Math(s) for dealing with numbers:
Math.Log10(Convert.ToDouble("1.0E-20")) // returns -20
To make sure your string input is a valid double use TryParse:
double d, result = 0.0;
if (Double.TryParse("1.0E-20", out d))
{
result = Math.Log10(d);
}
else
{
// handle error
}
Also, if you want to get the 1.0 (multiplier) from your input:
var d = Convert.ToDouble("1.0E-20");
var exponent = Math.Log10(d);
var multiplier = d / exponent;
No need for Regex when string methods can do wonders
string str = "1.0E-20";
str = str.Substring(str.IndexOf('E') + 1);
You can do that without Regex like:
string s = "1.0E-20";
string newStr = s.Substring(s.IndexOf('E') + 1);
Later you can parse the string to number like:
int number;
if (!int.TryParse(newStr, out number))
{
//invalid number
}
Console.WriteLine(number);
You can also use string.Split like:
string numberString = s.Split('E')[1]; //gives "-20"
Its better if you add check for string/array length when access string.Substring or accessing element 1 after split.
var x = str.IndexOf("E") != -1 ? str.Substring(str.IndexOf("E") + 1) : "1";
If you want to use regular expressions to achieve this, you should switch up your capture groups.
(([1-9]+\.[0-9]*)|([1-9]*\.[0-9]+)|([1-9]+))([eE])([-+]?[0-9]+)?
Group 6 will contain -20 with your given example with the regular expression above. Note how the parentheses have moved. We might need more information from you though. Do you have any more sample data? What's the end goal here?
I have some strings like below:
string num1 = "D123_1";
string num2 = "D123_2";
string num3 = "D456_11";
string num4 = "D456_22";
string num5 = "D_123_D";
string num5 = "_D_123";
I want to make a function that will do the following actions:
1- Checks if given string DOES HAVE an Underscore in it, and this underscore should be after some Numbers and Follow with some numbers: in this case 'num5' and 'num6' are invalid!
2- Replace the numbers after the last underscore with any desired string, for example I want 'num1 = "D123_1"' to be changed into 'D123_2'
So far I came with this idea but it is not working :( First I dont know how to check for criteria 1 and second the replace statement is not working:
private string CheckAndReplace(string given, string toAdd)
{
var changedString = given.Split('_');
return changedString[changedString.Length - 1] + toAdd;
}
Any help and tips will be appriciated
What you are looking for is a regular expression. This is (mostly) from the top of my head. But it should easily point you in the right direction. The regular expression works fine.
public static Regex regex = new Regex("(?<character>[a-zA-Z]+)(?<major>\\d+)_(?<minor>\\d+)",RegexOptions.CultureInvariant | RegexOptions.Compiled);
Match m = regex.Match(InputText);
if (m.Succes)
{
var newValue = String.Format("{0}{1}_{2}"m.Groups["character"].Value, m.Groups["major"].Value, m.Groups["minor"].Value);
}
In your code you split the String into an array of strings and then access the wrong index of the array, so it isn't doing what you want.
Try working with a substring instead. Find the index of the last '_' and then get the substring:
private string CheckAndReplace(string given, string toAdd) {
int index = given.LastIndexOf('_')+1;
return given.Substring(0,index) + toAdd;
}
But before that check the validity of the string (see other answers). This code fragment will break when there's no '_' in the string.
You could use a regular expression (this is not a complete implementation, only a hint):
private string CheckAndReplace(string given, string toAdd)
{
Regex regex = new Regex("([A-Z]*[0-9]+_)[0-9]+");
if (regex.IsMatch(given))
{
return string.Concat(regex.Match(given).Groups[1].Value, toAdd);
}
else
{
... do something else
}
}
Use a good regular expression implementation. .NET has standard implementation of them