String p = "f(x) = 0.0000001122*x^5 - 0.0000184003*x^4 + 0.0009611014*x^3 - 0.0179035548*x^2 - 0.7956585082*x + 79.9900932407";
String expr1 = p.ToString().Replace(" ", "");
var results = Regex.Matches(expr1, #"[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?").Cast<Match>().Select(m => m.Value).ToList();
Console.WriteLine(results[9]);
I am able to extract coefficients of the equation, but the output also contains the powers of x, which I don't want.
Can Anyone please assist me with this.
I am not much familiar with Regular Expression.
Thank you.
You can try with var results = Regex.Matches(expr1, #"\d+\.?\d+").Cast<Match>().Select(m => m.Value).ToList(); as long as coefficients are numbers represented only with digits.
\d+ matches one or more digits
\.? matches 0 or 1 "."
By regex it may be difficult; with Linq it would be easier: take every two coefficient, you get what you want:
Regex.Matches(expr1, #"[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?").Cast<Match>().Select(m => m.Value).Where ((x,i) => i%2==0).ToList();
It uses the indexed version of Where.
try this
String p = "f(x) = 0.0000001122*x^5 - 0.0000184003*x^4 + 0.0009611014*x^3 - 0.0179035548*x^2 - 0.7956585082*x + 79.9900932407";
String expr1 = p.ToString().Replace(" ", "");
var results = Regex.Matches(expr1, #"(?<coe>[-+]?[0-9]*\.[0-9]+)").Cast<Match>().Select(m => m.Groups["coe"].Value).ToList();
foreach (var result in results)
{
Console.WriteLine($"{result}");
}
Console.Read();
The result :
0.0000001122
-0.0000184003
+0.0009611014
-0.0179035548
-0.7956585082
+79.9900932407
Related
I want to format a string as a removing decimal and keep only integers , but the decimal contains some following zeros after the decimal. How do I format it such that those 0's disappear?
I have Input string data :
var xRaw= ",String30.0,String1.0,String0.0,String-1.0,StringOFF".Split(',').ToList();
How to get out put format : "30,1,0,-1,OFF"
var ValuesString = xRaw.Select(x => Regex.Replace(x, "[^OF0-9-,\\.]", "")).ToList()
.Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
Above regex will remove the string and keep required string "OFF" but its keeps another which is next to "." point.
You may fix your pattern (if it works enough well for you) by simply adding \.[0-9]+ alternative to also remove fractional parts of float numbers.
#"[^OF0-9-,.]|\.[0-9]+".
A better option is to keep OFF as a sequence of chars, not just any O or F:
Regex.Replace(x, #"(OFF)|[^0-9-,.]|\.[0-9]+", "$1")
Here, OFF is captured into Group 1 and $1 backreference restores it in the resulting string.
Umm... I think this fits your input string. Without knowing what variations can happen, there's no way to know if it works on all the data you might get.
var xRaw= ",String30.0,String1.0,String0.0,String1.0,StringOFF";
string result = String.Join(",",
Regex.Matches(xRaw, "\\d+.?\\d*|OFF")
.Cast<Match>()
.Select(m => {
decimal d;
if(decimal.TryParse(m.Value, out d))
return ((int)d).ToString();
return m.Value;
}));
Here is a simple solution:
var input = ",String30.0,String1.0,String0.0,String-1.0,StringOFF";
var output = Regex.Replace(Regex.Replace(input, #"[^OF\-\d.,]", ""), #"\.\d", "").TrimStart(',');
Working example: https://dotnetfiddle.net/8IordG
string giventxt = "text text 54654654200500.0000 text text";
string[] arry = giventxt.Split('.');
string arry1 = arry[1];
string[] arry2 = arry1.Split(' ');
string completestr = arry[0] + " " + arry2[1] + " " + arry2[2];
This might sound like a very basic question, but it's one that's given me quite a lot of trouble in C#.
Assume I have, for example, the following Strings known as my chosenTarget.titles:
2008/SD128934 - Wordz aaaaand more words (1233-26-21)
20998/AD1234 - Wordz and less words (1263-21-21)
208/ASD12345 - Wordz and more words (1833-21-21)
Now as you can see, all three Strings are different in some ways.
What I need is to extract a very specific part of these Strings, but getting the subtleties right is what confuses me, and I was wondering if some of you knew better than I.
What I know is that the Strings will always come in the following pattern:
yearNumber + "/" + aFewLetters + theDesiredNumber + " - " + descriptiveText + " (" + someDate + ")"
In the above example, what I would want to return to me would be:
128934
1234
12345
I need to extract theDesiredNumber.
Now, I'm not (that) lazy so I have made a few attempts myself:
var a = chosenTarget.title.Substring(chosenTarget.title.IndexOf("/") + 1, chosenTarget.title.Length - chosenTarget.title.IndexOf("/"));
What this has done is sliced out yearNumber and the /, leaving me with aFewLetter before theDesiredNumber.
I have a hard time properly removing the rest however, and I was wondering if any of you could aid me in the matter?
It sounds as if you only need to extract the number behind the first / which ends at -. You could use a combination of string methods and LINQ:
int startIndex = str.IndexOf("/");
string number = null;
if (startIndex >= 0 )
{
int endIndex = str.IndexOf(" - ", startIndex);
if (endIndex >= 0)
{
startIndex++;
string token = str.Substring(startIndex, endIndex - startIndex); // SD128934
number = String.Concat(token.Where(char.IsDigit)); // 128934
}
}
Another mainly LINQ approach using String.Split:
number = String.Concat(
str.Split(new[] { " - " }, StringSplitOptions.None)[0]
.Split('/')
.Last()
.Where(char.IsDigit));
Try this:
int indexSlash = chosenTarget.title.IndexOf("/");
int indexDash = chosenTarget.title.IndexOf("-");
string out = new string(chosenTarget.title.Substring(indexSlash,indexDash-indexSlash).Where(c => Char.IsDigit(c)).ToArray());
You can use a regex:
var pattern = "(?:[0-9]+/\w+)[0-9]";
var matcher = new Regex(pattern);
var result = matcher.Matches(yourEntireSetOfLinesInAString);
Or you can loop every line and use Match instead of Matches. In this case you don't need to build a "matcher" in every iteration but build it outside the loop
Regex is your friend:
(new [] {"2008/SD128934 - Wordz aaaaand more words (1233-26-21)",
"20998/AD1234 - Wordz and less words (1263-21-21)",
"208/ASD12345 - Wordz and more words (1833-21-21)"})
.Select(x => new Regex(#"\d+/[A-Z]+(\d+)").Match(x).Groups[1].Value)
The pattern you had recognized is very important, here is the solution:
const string pattern = #"\d+\/[a-zA-Z]+(\d+).*$";
string s1 = #"2008/SD128934 - Wordz aaaaand more words(1233-26-21)";
string s2 = #"20998/AD1234 - Wordz and less words(1263-21-21)";
string s3 = #"208/ASD12345 - Wordz and more words(1833-21-21)";
var strings = new List<string> { s1, s2, s3 };
var desiredNumber = string.Empty;
foreach (var s in strings)
{
var match = Regex.Match(s, pattern);
if (match.Success)
{
desiredNumber = match.Groups[1].Value;
}
}
I would use a RegEx for this, the string you're looking for is in Match.Groups[1]
string composite = "2008/SD128934 - Wordz aaaaand more words (1233-26-21)";
Match m= Regex.Match(composite,#"^\d{4}\/[a-zA-Z]+(\d+)");
if (m.Success) Console.WriteLine(m.Groups[1]);
The breakdown of the RegEx is as follows
"^\d{4}\/[a-zA-Z]+(\d+)"
^ - Indicates that it's the beginning of the string
\d{4} - Four digits
\/ - /
[a-zA-Z]+ - More than one letters
(\d+) - More than one digits (the parenthesis indicate that this part is captured as a group - in this case group 1)
How an I use regex to find anything between 2 ASCII codes?
ASCII code STX (\u0002) and ETX (\u0003)
Example string "STX,T1,ETXSTX,1,1,1,1,1,1,ETXSTX,A,1,0,B,ERRETX"
Using Regex on the above my matches should be
,T1,
,1,1,1,1,1,1,
,A,1,0,B,ERR
Did a bit of googling and I tried the following pattern but it didn't find anything.
#"^\u0002.*\u0003$"
UPDATE: Thank you all, some great answers below and all seem to work!
You could use Regex.Split.
var input = (char)2 + ",T1," + (char)3 + (char)2 + ",1,1,1,1,1,1," + (char)3 + (char)2 + ",A,1,0,B,ERR" + (char)3;
var result = Regex.Split(input, "\u0002|\u0003").Where(r => !String.IsNullOrEmpty(r));
You may use a non-regex solution, too (based on Wyatt's answer):
var result = input.Split(new[] {'\u0002', '\u0003'}) // split with the known char delimiters
.Where(p => !string.IsNullOrEmpty(p)) // Only take non-empty ones
.ToList();
A Regex solution I suggested in comments:
var res = Regex.Matches(input, "(?s)\u0002(.*?)\u0003")
.OfType<Match>()
.Select(p => p.Groups[1].Value)
.ToList();
var s = "STX,T1,ETXSTX,1,1,1,1,1,1,ETXSTX,A,1,0,B,ERRETX";
s = s.Replace("STX", "\u0002");
s = s.Replace("ETX", "\u0003");
var result1 = Regex.Split(s, #"[\u0002\u0003]").Where(a => a != String.Empty).ToList();
result1.ForEach(a=>Console.WriteLine(a));
Console.WriteLine("------------ OR WITHOUT REGEX ---------------");
var result2 = s.Split(new char[] { '\u0002','\u0003' }, StringSplitOptions.RemoveEmptyEntries).ToList();
result2.ForEach(a => Console.WriteLine(a));
output:
,T1,
,1,1,1,1,1,1,
,A,1,0,B,ERR
------------ OR WITHOUT REGEX ---------------
,T1,
,1,1,1,1,1,1,
,A,1,0,B,ERR
I want to split a string to an array of sub-strings. The string is delimited by space, but space may appear inside the sub-strings too. And spliced strings must be of the same length.
Example:
"a b aab bb aaa" -> "a b", "aab", "bb ", "aaa"
I have the following code:
var T = Regex.Split(S, #"(?<=\G.{4})").Select(x => x.Substring(0, 3));
But I need to parameterize this code, split by various length(3, 4, 5 or n) and I don't know how do this. Please help.
If impossible to parameterize Regex, fully linq version ok.
You can use the same regex, but "parameterize" it by inserting the desired number into the string.
In C# 6.0, you can do it like this:
var n = 5;
var T = Regex.Split(S, $#"(?<=\G.{{{n}}})").Select(x => x.Substring(0, n-1));
Prior to that you could use string.Format:
var n = 5;
var regex = string.Format(#"(?<=\G.{{{0}}})", n);
var T = Regex.Split(S, regex).Select(x => x.Substring(0, n-1));
It seems rather easy with LINQ:
var source = "a b aab bb aaa";
var results =
Enumerable
.Range(0, source.Length / 4 + 1)
.Select(n => source.Substring(n * 4, 3))
.ToList();
Or using Microsoft's Reactive Framework's team's Interactive Extensions (NuGet "Ix-Main") and do this:
var results =
source
.Buffer(3, 4)
.Select(x => new string(x.ToArray()))
.ToList();
Both give you the output you require.
A lookbehind (?<=pattern) matches a zero-length string. To split using spaces as delimiters, the match has to actually return a "" (the space has to be in the main pattern, outside the lookbehind).
Regex for length = 3: #"(?<=\G.{3}) " (note the trailing space)
Code for length n:
var n = 3;
var S = "a b aab bb aaa";
var regex = #"(?<=\G.{" + n + #"}) ";
var T = Regex.Split(S, regex);
Run this code online
Input string is: name = valu\=e;
I want to split it with Regex to: name and valu\=e;.
So split expresion should split on char = which is not prefixed by \.
I want to keep spaces after name or before valu\=e etc. Couldn't it show here because SO trims ``.
EDIT: Input string can contains many name=value pairs. Example: name=value;name2=value2;.
You can use this pattern:
#"(?<!\\)="
(?<!..) is a negative lookbehind assertion and means:"not preceded by"
Heinzi question is interesting. If you choose that an even number of backslashes doesn't escape the equal sign, you must replace the pattern by:
#"(?<![^\\](?:\\{2})*\\)="
Instead of using regular expressions, you might use 'regular' code. :)
string items = "name=value;name2 = valu= = e2";
// Split the list on items.
var itemlist = items.Split(';');
// Split each item after the first '='.
var nameValueArrayList = itemlist.Select(s => s.Split("=".ToCharArray(), 2));
// Convert the list of arrays to a dictionary
var nameValues = nameValueArrayList.ToDictionary(i => i[0], i => i[1]);
MessageBox.Show("<<<" + nameValues["name2 "] + ">>>");
Or in short:
string items = "name=value;name2 = valu= = e2";
var nameValues = items
.Split(';')
.Select(s => s.Split("=".ToCharArray(), 2))
.ToDictionary(i => i[0], i => i[1]);
MessageBox.Show("<<<" + nameValues["name2 "] + ">>>");
I personally think that code like this is easier to maintain or pull apart and modify when the specs change. And it gives you an actual dictionary from which you can pull values by their key.
Maybe it's possible to write this even a little shorter, but I'm still practicing with this. :)
(?<name>[^=]+)=(?<value>[^;]+;)
then use the named groups "name" and "value" to retrieve each part separately.
e.g:
var matches = System.Text.RegularExpressions.Regex.Matches("myInput", #"(?<name>[^=]+)=(?<value>[^;]+;)");
foreach(Match match in matches)
{
var name = match.Groups["name"];
var value = match.Groups["value"];
doSomething(name, value);
}
EDIT:
I don't know why you say it won't work, here is what I get in LinqPad using the input you gave me in the comments:
void Main()
{
var matches = System.Text.RegularExpressions.Regex.Matches(#"zenek=ben\\\;\\ek;juzek=jozek;benek2=true;krowa=-2147483648;du-pa=\\\\\\3/\\\=3\;3\;;", #"(?<name>[^=]+)=(?<value>[^;]+;)");
foreach(Match match in matches)
{
var name = match.Groups["name"].Value;
var value = match.Groups["value"].Value;
("Name: "+name).Dump();
("Value: "+value).Dump();
}
}
Results:
Name: zenek
Value: ben\\\;
Name: \\ek;juzek
Value: jozek;
Name: benek2
Value: true;
Name: krowa
Value: -2147483648;
Name: du-pa
Value: \\\\\\3/\\\=3\;