I have been looking at a few posts on SO about how to deserialize a date in a json string.
The posts mention doing a replace on the string to reformat the Date parts.
the json string looks like this:
"/Date(1336258800000)/\"
apparently what I need to get to is this:
"new Date(1336258800000)"
The trouble is as soon as I try and to a replace, or indexOf ')/\' it doesnt find the string to replace (indexOf is -1)
can anyone see what im doing wrong?
JavaScriptSerializer jss = new JavaScriptSerializer();
//Fix an issue with Json Dates
string json = eventArgument.Replace( #"/Date(", "new Date(" ).Replace( #")/\", ")" );
int index = json.IndexOf( #")/\", 0 );
WorkPattern wp = jss.DeserializeObject( json ) as WorkPattern;
here is the full json string:
"{\"WorkPatternDays\":[{\"WorkPatternDayShifts\":[{\"WorkPatternDayShiftRates\":[{\"Duration\":8.5,\"Sequence\":0,\"WorkPatternDayShiftID\":186,\"WorkPatternDayShiftRateID\":105,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"}],\"WorkPatternDayShiftBreaks\":[{\"PaidBreak\":true,\"Duration\":1,\"EndTime\":\"/Date(1336050000000)/\",\"StartTime\":\"/Date(1336046400000)/\",\"WorkPatternDayShiftID\":186,\"WorkPatternDayShiftBreakID\":284,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"},{\"PaidBreak\":false,\"Duration\":0.25,\"EndTime\":\"/Date(1336058100000)/\",\"StartTime\":\"/Date(1336057200000)/\",\"WorkPatternDayShiftID\":186,\"WorkPatternDayShiftBreakID\":285,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"}],\"Duration\":8.5,\"EndTime\":\"/Date(1336062600000)/\",\"StartTime\":\"/Date(1336032000000)/\",\"WorkPatternDayID\":186,\"WorkPatternDayShiftID\":186,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"}],\"DayOfWeek\":1,\"DayOfWeekNumber\":1,\"WorkPatternID\":105,\"WorkPatternDayID\":186,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"},{\"WorkPatternDayShifts\":[{\"WorkPatternDayShiftRates\":[],\"WorkPatternDayShiftBreaks\":[{\"PaidBreak\":true,\"Duration\":0.5,\"EndTime\":\"/Date(1336041000000)/\",\"StartTime\":\"/Date(1336039200000)/\",\"WorkPatternDayShiftID\":187,\"WorkPatternDayShiftBreakID\":286,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"}],\"Duration\":5.5,\"EndTime\":\"/Date(1336046400000)/\",\"StartTime\":\"/Date(1336026600000)/\",\"WorkPatternDayID\":187,\"WorkPatternDayShiftID\":187,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"}],\"DayOfWeek\":3,\"DayOfWeekNumber\":3,\"WorkPatternID\":105,\"WorkPatternDayID\":187,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"}],\"WorkPatternName\":\"Naths Test Work Pattern\",\"WorkPatternID\":105,\"Deleted\":false,\"UpdatedUser\":\"\",\"UpdatedDate\":\"/Date(1336258800000)/\"}"
A bit more info to see how it all fits together:
code behind:
public override void DataBind()
{
try
{
if ( this.WorkPattern != null )
{
//Create a javascript serializer
JavaScriptSerializer jss = new JavaScriptSerializer();
//Get the serialised object as a json string
string json = jss.Serialize( this.WorkPattern );
//Run the jquery code
base.RunjQueryCode(
String.Format( "loadWorkPattern({0});", json ) );
jss = null;
}
}
catch ( Exception )
{
throw;
}
}
protected override void HandlePostbacks( string eventTarget, string eventArgument )
{
try
{
switch ( eventTarget )
{
case "Save":
JavaScriptSerializer jss = new JavaScriptSerializer();
//Fix an issue with Json Dates
string json = eventArgument.Replace( #"/Date(", "new Date(" ).Replace( #")/\", ")" );
int index = json.IndexOf( #")/\\", 0 );
WorkPattern wp = jss.DeserializeObject( json ) as WorkPattern;
object o = jss.Deserialize<WorkPattern>( json );
break;
default: break;
}
base.HandlePostbacks( eventTarget, eventArgument );
}
catch ( Exception )
{
throw;
}
}
Markup / js:
function loadWorkPattern(jsonData) {
//Store the work pattern
_workPattern = jsonData;
//Loop through the work pattern days
$.each(_workPattern.WorkPatternDays, function (key, workPatternDay) {
//Loop through each shift
$.each(workPatternDay.WorkPatternDayShifts, function (key, workPatternShift) {
addShift(workPatternShift, workPatternDay.DayOfWeekNumber);
//Loop through each break
$.each(workPatternShift.WorkPatternDayShiftBreaks, function (key, workPatternDayShiftBreak) {
addBreak(workPatternDayShiftBreak);
});
});
});
}
function saveWorkPattern() {
__doPostBack('Save', JSON.stringify(_workPattern));
}
Im calling JSON.stringify to serialize the serialize the stored object before sending back to the server, is this what im doing wrong?
UPDATE
This is the working code:
string json = eventArgument.Replace( #"/Date(", "\\/Date(" ).Replace( #")/", ")\\/" );
Try int index = json.IndexOf( #")/\\", 0 ); - put another slash before the slash
Update
JavaScriptSerializer s = new JavaScriptSerializer();
string date = s.Serialize(DateTime.Now);
int index = date.IndexOf(#")\/", 0);
Console.WriteLine(index); // index = 21
Update - solution
The problem is the the initial string is /Date(1336258800000)/, but not /Date(1336258800000)/\ as the last slash is an escape of the " character in the JSON.
And the format for the desiarization should be dirrerent, so the working solution is
string json = eventArgument.Replace( #"/Date(", "\\/Date(" ).Replace( #")/", ")\\/" );
I used regular expressions, hope that's not a problem. The regex detect the /Date(NUMBER)/\ and gets the NUMBER as a group in the regular expression match so I use that to replace everything in the dateTimeJson that matches the regex specified in its constructor with new Date(NUMBER).
//the source JSON
string dateTimeJson = "/Date(1336258800000)/\\";
string result = "";
//you might want to do a quick IndexOf("Date") to make sure that there is a date
//so you won't trouble yourselve with regex computation unnecessarily. performance?
//find Date(NUMBER) matches and get the NUMBER then use it again with new Date in the
//call to replace
System.Text.RegularExpressions.MatchCollection matches = null;
System.Text.RegularExpressions.Regex regex = null;
try
{
//at the end is one forwared slash for regex escaping \ and another is the \ that is escaped
regex = new System.Text.RegularExpressions.Regex(#"/Date\(([0-9]*)\)/\\");
matches = regex.Matches(dateTimeJson);
string dateNumber = matches[0].Groups[1].Value;
result = regex.Replace(dateTimeJson, "new Date(" + dateNumber + ")");
}
catch (Exception iii)
{
//MessageBox.Show(iii.ToString());
}
MessageBox.Show(result);
Related
Can somebody please tell me why a space comes up with 2 matches for the below pattern?
((?<key>(?:((?!\d)\w+(?:\.(?!\d)\w+)*)\.)?((?!\d)\w+)):(?<value>([^ "]+)|("[^"]*?")+))*
Trying to match the following cases:
var body = "Key:Hello";
var body = "Key:\"Hello\"";
var body = "Key1:Hello Key2:\"Goodbye\"";
This may provide more context:
pattern = #"((?<key>" + StringExtensions.REGEX_IDENTIFIER_MIDSTRING + "):(?<value>([^ \"]+)|(\"[^\"]*?\")+))*";
My goal is to pull the keys, values out of a command-line like string in the form of [key]:[value] with optional repeats. Values can either be a with no spaces or in quotes with spaces.
Probably right there in front of me but I'm not seeing it.
Probably because “.”, because a period in regex, marches every character except line breaks
I took a different approach:
public static Dictionary<string, string> GetCommandLineKeyValues(this string commandLine)
{
var keyValues = new Dictionary<string, string>();
var pattern = #"(?<command>(" + StringExtensions.REGEX_IDENTIFIER + " )?)(?<args>.*)";
var args = commandLine.RegexGet(pattern, "args");
Match match;
if (args.Length > 0)
{
string key;
string value;
pattern = #" ?(?<key>" + StringExtensions.REGEX_IDENTIFIER_MIDSTRING + ")*?:(?<value>([^ \"]+)|(\"[^\"]*?\")+)";
do
{
match = args.RegexGetMatch(pattern);
if (match == null)
{
break;
}
key = match.Groups["key"].Value;
value = match.Groups["value"].Value;
keyValues.Add(key, value);
args = match.Replace(args, string.Empty);
}
while (args.RegexIsMatch(pattern));
}
return keyValues;
}
I took what I call the "pac-man" approach to Regex.. match, eat (hence the Match.Replace), and continue matching.
For convenience:
public const string REGEX_IDENTIFIER = #"^(?:((?!\d)\w+(?:\.(?!\d)\w+)*)\.)?((?!\d)\w+)$";
I found some solutions for my problem, which is quite simple:
I have a string, which is looking like this:
"\r\nContent-Disposition: form-data; name=\"ctl00$cphMainContent$grid$ctl03$ucPicture$ctl00\""
My goal is to break it down, so I have a Dictionary of values, like:
Key = "name", value ? "ctl..."
My approach was: Split it by "\r\n" and then by the equal or the colon sign.
This worked fine, but then some funny Tester uploaded a file with all allowed charactes, which made the String looking like this:
"\r\nContent-Disposition: form-data; name=\"ctl00_cphMainContent_grid_ctl03_ucPicture_btnUpload$fileUpload\"; filename=\"C:\\Users\\matthias.mueller\\Desktop\\- ie+![]{}_-´;,.$¨##ç %&()=~^`'.jpg\"\r\nContent-Type: image/jpeg"
Of course, the simple splitting doesn't work anymore, since it splits now the filename.
I corrected this by reading out "filename=" and escaping the signs I'm looking to split, and then creating a regex.
Now comes my problem: I found two Regex-samples, which could do the work for the equal sign, the semicolon and the colon. one is:
[^\\]=
The other one I found was:
(?<!\\\\)=
The problem is, the first one doesn't only split, but it splits the equal sign and one character before this sign, which means my key in the Dictionary is "nam" instead of "name"
The second one works fine on this matter, but it still splits the escaped equal sign in the filename.
Is my approach for this problem even working? Would there be a better solution for this? And why is the first Regex cutting a character?
Edit: To avoid confusion, my escaped String looks like this:
"Content-Disposition: form-data; name=\"ctl00_cphMainContent_grid_ctl03_ucPicture_btnUpload$fileUpload\"; filename=\"C\:\Users\matthias.mueller\Desktop\- ie+![]{}_-´\;,.$¨##ç %&()\=~^`'.jpg\""
So I want basically: Split by equal Sign EXCEPT the escaped ones. By the way: The string here shows only one \, but there are 2.
Edit 2: OK seems like I have a working solution, but it's so ugly:
Dictionary<string, string> ParseHeader(byte[] bytes, int pos)
{
Dictionary<string, string> items;
string header;
string[] headerLines;
int start;
int end;
string input = _encoding.GetString(bytes, pos, bytes.Length - pos);
start = input.IndexOf("\r\n", 0);
if (start < 0) return null;
end = input.IndexOf("\r\n\r\n", start);
if (end < 0) return null;
WriteBytes(false, bytes, pos, end + 4 - 0); // Write the header to the form content
header = input.Substring(start, end - start);
items = new Dictionary<string, string>();
headerLines = Regex.Split(header, "\r\n");
Regex regLineParts = new Regex(#"(?<!\\\\);");
Regex regColon = new Regex(#"(?<!\\\\):");
Regex regEqualSign = new Regex(#"(?<!\\\\)=");
foreach (string hl in headerLines)
{
string workString = hl;
//Escape the Semicolon in filename
if (hl.Contains("filename"))
{
String orig = hl.Substring(hl.IndexOf("filename=\"") + 10);
orig = orig.Substring(0, orig.IndexOf('"'));
string toReplace = orig;
toReplace = toReplace.Replace(toReplace, toReplace.Replace(";", #"\\;"));
toReplace = toReplace.Replace(toReplace, toReplace.Replace(":", #"\\:"));
toReplace = toReplace.Replace(toReplace, toReplace.Replace("=", #"\\="));
workString = hl.Replace(orig, toReplace);
}
string[] lineParts = regLineParts.Split(workString);
for (int i = 0; i < lineParts.Length; i++)
{
string[] p;
if (i == 0)
p = regColon.Split(lineParts[i]);
else
p = regEqualSign.Split(lineParts[i]);
if (p.Length == 2)
{
string orig = p[0];
orig = orig.Replace(#"\\;", ";");
orig = orig.Replace(#"\\:", ":");
orig = orig.Replace(#"\\=", "=");
p[0] = orig;
orig = p[1];
orig = orig.Replace(#"\\;", ";");
orig = orig.Replace(#"\\:", ":");
orig = orig.Replace(#"\\=", "=");
p[1] = orig;
items.Add(p[0].Trim(), p[1].Trim());
}
}
}
return items;
}
Needs some further testing.
I had a go at writing a parser for you. It handles literal strings, like "here is a string", as the values in name-value pairs. I've also written a few tests, and the last shows an '=' character inside a literal string. It also handles escaping quotes (") inside literal strings by escaping as \" -- I'm not sure if this is right, but you could change it.
A quick explanation. I first find anything that looks like a literal string and replace it with a value like PLACEHOLDER8230498234098230498. This means the whole thing is now literal name-value pairs; eg
key="value"
becomes
key=PLACEHOLDER8230498234098230498
The original string value is stored off in the literalStrings dictionary for later.
So now we split on semicolons (to get key=value strings) and then on equals, to get the proper key/value pairs.
Then I substitute the placeholder values back in before returning the result.
public class HttpHeaderParser
{
public NameValueCollection Parse(string header)
{
var result = new NameValueCollection();
// 'register' any string values;
var stringLiteralRx = new Regex(#"""(?<content>(\\""|[^\""])+?)""", RegexOptions.IgnorePatternWhitespace);
var equalsRx = new Regex("=", RegexOptions.IgnorePatternWhitespace);
var semiRx = new Regex(";", RegexOptions.IgnorePatternWhitespace);
Dictionary<string, string> literalStrings = new Dictionary<string, string>();
var cleanedHeader = stringLiteralRx.Replace(header, m =>
{
var replacement = "PLACEHOLDER" + Guid.NewGuid().ToString("N");
var stringLiteral = m.Groups["content"].Value.Replace("\\\"", "\"");
literalStrings.Add(replacement, stringLiteral);
return replacement;
});
// now it's safe to split on semicolons to get name-value pairs
var nameValuePairs = semiRx.Split(cleanedHeader);
foreach(var nameValuePair in nameValuePairs)
{
var nameAndValuePieces = equalsRx.Split(nameValuePair);
var name = nameAndValuePieces[0].Trim();
var value = nameAndValuePieces[1];
string replacementValue;
if (literalStrings.TryGetValue(value, out replacementValue))
{
value = replacementValue;
}
result.Add(name, value);
}
return result;
}
}
There's every chance there are some proper bugs in it.
Here's some unit tests you should incorporate, too;
[TestMethod]
public void TestMethod1()
{
var tests = new[] {
new { input=#"foo=bar; baz=quux", expected = #"foo|bar^baz|quux"},
new { input=#"foo=bar;baz=""quux""", expected = #"foo|bar^baz|quux"},
new { input=#"foo=""bar"";baz=""quux""", expected = #"foo|bar^baz|quux"},
new { input=#"foo=""b,a,r"";baz=""quux""", expected = #"foo|b,a,r^baz|quux"},
new { input=#"foo=""b;r"";baz=""quux""", expected = #"foo|b;r^baz|quux"},
new { input=#"foo=""b\""r"";baz=""quux""", expected = #"foo|b""r^baz|quux"},
new { input=#"foo=""b=r"";baz=""quux""", expected = #"foo|b=r^baz|quux"},
};
var parser = new HttpHeaderParser();
foreach(var test in tests)
{
var actual = parser.Parse(test.input);
var actualAsString = String.Join("^", actual.Keys.Cast<string>().Select(k => string.Format("{0}|{1}", k, actual[k])));
Assert.AreEqual(test.expected, actualAsString);
}
}
Looks to me like you'll need a bit more of a solid parser for this than a regex split. According to this page the name/value pairs can either be 'raw';
x=1
or quoted;
x="foo bar baz"
So you'll need to look for a solution that not only splits on the equals, but ignores any equals inside;
x="y=z"
It might be that there is a better or more managed way for you to access this info. If you are using a classic ASP.NET WebForms FileUpload control, you can access the filename using the properties of the control, like
FileUpload1.HasFile
FileUpload1.FileName
If you're using MVC, you can use the HttpPostedFileBase class as a parameter to the action method. See this answer
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
// Verify that the user selected a file
if (file != null && file.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
// redirect back to the index action to show the form once again
return RedirectToAction("Index");
}
This:
(?<!\\\\)=
matches = not preceded by \\.
It should be:
(?<!\\)=
(Make sure you use # (verbatim) strings for the regex, to avoid confusion)
I have a string
"[\"1,1\",\"2,2\"]"
and I want to turn this string onto this
1,1,2,2
I am using Replace function for that like
obj.str.Replace("[","").Replace("]","").Replace("\\","");
But it does not return the expected result.
Please help.
You haven't removed the double quotes. Use the following:
obj.str = obj.str.Replace("[","").Replace("]","").Replace("\\","").Replace("\"", "");
Here is an optimized approach in case the string or the list of exclude-characters is long:
public static class StringExtensions
{
public static String RemoveAll(this string input, params Char[] charactersToRemove)
{
if(string.IsNullOrEmpty(input) || (charactersToRemove==null || charactersToRemove.Length==0))
return input;
var exclude = new HashSet<Char>(charactersToRemove); // removes duplicates and has constant lookup time
var sb = new StringBuilder(input.Length);
foreach (Char c in input)
{
if (!exclude.Contains(c))
sb.Append(c);
}
return sb.ToString();
}
}
Use it in this way:
str = str.RemoveAll('"', '[', ']', '\\');
// or use a string as "remove-array":
string removeChars = "\"{[]\\";
str = str.RemoveAll(removeChars.ToCharArray());
You should do following:
obj.str = obj.str.Replace("[","").Replace("]","").Replace("\"","");
string.Replace method does not replace string content in place. This means that if you have
string test = "12345" and do
test.Replace("2", "1");
test string will still be "12345". Replace doesn't change string itself, but creates new string with replaced content. So you need to assign this new string to a new or same variable
changedTest = test.Replace("2", "1");
Now, changedTest will containt "11345".
Another note on your code is that you don't actually have \ character in your string. It's only displayed in order to escape quote character. If you want to know more about this, please read MSDN article on string literals.
how about
var exclusions = new HashSet<char>(new[] { '"', '[', ']', '\\' });
return new string(obj.str.Where(c => !exclusions.Contains(c)).ToArray());
To do it all in one sweep.
As Tim Schmelter writes, if you wanted to do it often, especially with large exclusion sets over long strings, you could make an extension like this.
public static string Strip(
this string source,
params char[] exclusions)
{
if (!exclusions.Any())
{
return source;
}
var mask = new HashSet<char>(exclusions);
var result = new StringBuilder(source.Length);
foreach (var c in source.Where(c => !mask.Contains(c)))
{
result.Append(c);
}
return result.ToString();
}
so you could do,
var result = "[\"1,1\",\"2,2\"]".Strip('"', '[', ']', '\\');
Capture the numbers only with this regular expression [0-9]+ and then concatenate the matches:
var input = "[\"1,1\",\"2,2\"]";
var regex = new Regex("[0-9]+");
var matches = regex.Matches(input).Cast<Match>().Select(m => m.Value);
var result = string.Join(",", matches);
I have a javascript function that returns an array.
I would like to know
(a) how to call the Javascript function in OnInit or Onload
(b) The javascript function returns an array and I want it to be stored within an array in my c# code.
Please suggest.
Thanks.
Update1: Javascript function is something like below.
function RenderUrl()
{
var url = "http://myurl.com/mypage?Id=420&Width=30"; //this is a dummy url.
var qsBegin = url.indexOf("?");
var qsPattern = new RegExp("[?&]([^=]*)=([^&]*)", "ig");
var match = qsPattern.exec(url);
var params = new Array();
while (match != null)
{
var matchID = match[1];
if ( matchID.charAt(0) == "&" )
{
matchID = matchID.substr(1);
}
if ( params[match[1]] != null && !(params[match[1]] instanceof Array) )
{
var subArray = new Array();
subArray.push(params[match[1]]);
subArray.push(unescape(match[2]));
params[match[1]] = subArray;
}
else if ( params[match[1]] != null && params[match[1]] instanceof Array )
{
params[match[1]].push(unescape(match[2]));
}
else
{
params[match[1]]=unescape(match[2]);
}
match = qsPattern.exec(url);
}
return params;
}
Update 2: My c# code so far (not working as expected but I am checking currently)
private void ParseUrl(string Url)
{
int WhereToBegin = Url.IndexOf("?");
string pattern = #"[?&]([^=]*)=([^&]*)";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = rgx.Matches(Url);
while (matches != null)
{
string matchID = matches[0].ToString();
if (matchID.Substring(0, 1) == "&")
{
matchID = matchID.Substring(1);
}
//Push to the new array named PARAMS here (under construction)
..
..
//End array construction.
matches = rgx.Matches(Url);
}
//Finally return the array once it is working fine.
}
The javascript that you posted just extracts the parameters from the URL of the page. You don't need to use javascript to get that information in ASP.NET, you can get it from C# directly by looking at Request.QueryString (among other ways)
Last time I checked, you cannot call client side code from server side code.
I have strings and each contain a value of RowKey stored like this:
data-RowKey=029
This occurs only once in each file. Is there some way I can get the number out with a C# function or do I have to write some kind of select myself. I have a team mate who suggested linq but I'm not sure if this even works on strings and I don't know how I could use this.
Update:
Sorry I changed this from file to string.
Linq does not really help you here. Use a regular expression to extract the number:
data-Rowkey=(\d+)
Update:
Regex r = new Regex(#"data-Rowkey=(\d+)");
string abc = //;
Match match = r.Match(abc);
if (match.Success)
{
string rowKey = match.Groups[1].Value;
}
Code:
public string ExtractRowKey(string filePath)
{
Regex r = new Regex(#"data-Rowkey=(\d+)");
using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Match match = r.Match(line);
if (match.Success) return match.Groups[1].Value;
}
}
}
Assuming that it only exists once in a file, i would even throw an exception otherwise:
String rowKey = null;
try
{
rowKey = File.ReadLines(path)
.Where(l => l.IndexOf("data-RowKey=") > -1)
.Select(l => l.Substring(12 + l.IndexOf("data-RowKey=")))
.Single();
}
catch (InvalidOperationException) {
// you might want to log this exception instead
throw;
}
Edit: The simple approach with a string, take the first occurence which is always of length 3:
rowKey = text.Substring(12 + text.IndexOf("data-RowKey="), 3);
Assuming following
File must contain data-Row (with exact match including case)
Number length is 3
Following is the code snippet
var fileNames = Directory.GetFiles("rootDirPath");
var tuples = new List<Tuple<String, int>>();
foreach(String fileName in fileNames)
{
String fileData =File.ReadAllText(fileName) ;
int index = fileData.IndexOf("data-RowKey=");
if(index >=0)
{
String numberStr = fileData.Substring(index+12,3);// ASSUMING data-RowKey is always found, and number length is always 3
int number = 0;
int.TryParse(numberStr, out number);
tuples.Add(Tuple.Create(fileName, number));
}
}
Regex g = new Regex(#"data-RowKey=(?<Value>\d+)");
using (StreamReader r = new StreamReader("myFile.txt"))
{
string line;
while ((line = r.ReadLine()) != null)
{
Match m = g.Match(line);
if (m.Success)
{
string v = m.Groups["Value"].Value;
// ...
}
}
}