|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Regex questionI am wonding if anyone knows a good Regex expression that would pull a valid date from a string. I have used: strValue = Regex.Replace(valueIn, @"[^\d/]", ""); which works most of the time. But I have some cases where I have strings like: 05/07/08(-4%) 09/19/08 DOM 55 09/19/2008 DOM 53 FOR 09/15/08 -23 Thanks, Tom What is really strange is that 05/07/08(-4%) is converting to:
05/07/084 Convert.ToDateTime is change this to: 05/07/0084 12:00:00 AM???? But Sql says it is invalid and gives me an error: Message: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM. It turns out all of these examples die in SQL but pass in VS. The code I use is: public static DateTime? CleanDates(string valueIn) { DateTime? datValue = null; string strValue; strValue = Regex.Replace(valueIn, @"[^\d/]", ""); try { datValue = Convert.ToDateTime(strValue); } catch { datValue = null; } return datValue; } I would have assumed it would take the Catch, but doesn't. Why is this? Thanks, Tom Show quoteHide quote "tshad" <t**@dslextreme.com> wrote in message news:OpJPJBkYJHA.5828@TK2MSFTNGP03.phx.gbl... > This is really a regex question. > > I am wonding if anyone knows a good Regex expression that would pull a > valid date from a string. > > I have used: > > strValue = Regex.Replace(valueIn, @"[^\d/]", ""); > > which works most of the time. > > But I have some cases where I have strings like: > > 05/07/08(-4%) > 09/19/08 DOM 55 > 09/19/2008 DOM 53 > FOR 09/15/08 -23 > > Thanks, > > Tom > > > tshad wrote:
> What is really strange is that 05/07/08(-4%) is converting to: SQLServer DATETIME apparently has a different range than> > 05/07/084 > > Convert.ToDateTime is change this to: 05/07/0084 12:00:00 AM???? > > But Sql says it is invalid and gives me an error: > > Message: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and > 12/31/9999 11:59:59 PM. > > It turns out all of these examples die in SQL but pass in VS. ..NET System.DateTime - that is not particular surprising. Arne
Show quote
Hide quote
"Arne Vajhøj" <a***@vajhoej.dk> wrote in message I agree. I don't know what the range is, but that wouldn't help anyway. It news:494c4b15$0$90272$14726298@news.sunsite.dk... > tshad wrote: >> What is really strange is that 05/07/08(-4%) is converting to: >> >> 05/07/084 >> >> Convert.ToDateTime is change this to: 05/07/0084 12:00:00 AM???? >> >> But Sql says it is invalid and gives me an error: >> >> Message: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM >> and 12/31/9999 11:59:59 PM. >> >> It turns out all of these examples die in SQL but pass in VS. > > SQLServer DATETIME apparently has a different range than > .NET System.DateTime - that is not particular surprising. can be a valid date and not be THE valid date - which this showed. I wasn't expecting this - but should have. Thanks, Tom Show quoteHide quote > > Arne tshad wrote:
Show quoteHide quote > "Arne Vajhøj" <a***@vajhoej.dk> wrote in message http://msdn.microsoft.com/en-us/library/system.datetime.aspx> news:494c4b15$0$90272$14726298@news.sunsite.dk... >> tshad wrote: >>> What is really strange is that 05/07/08(-4%) is converting to: >>> >>> 05/07/084 >>> >>> Convert.ToDateTime is change this to: 05/07/0084 12:00:00 AM???? >>> >>> But Sql says it is invalid and gives me an error: >>> >>> Message: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM >>> and 12/31/9999 11:59:59 PM. >>> >>> It turns out all of these examples die in SQL but pass in VS. >> SQLServer DATETIME apparently has a different range than >> .NET System.DateTime - that is not particular surprising. > > I agree. I don't know what the range is, but that wouldn't help anyway. It > can be a valid date and not be THE valid date - which this showed. I wasn't > expecting this - but should have. The DateTime value type represents dates and times with values ranging from 12:00:00 midnight, January 1, 0001 Anno Domini (Common Era) through 11:59:59 P.M., December 31, 9999 A.D. (C.E.) Time values are measured in 100-nanosecond units called ticks, and a particular date is the number of ticks since 12:00 midnight, January 1, 0001 A.D. (C.E.) in the GregorianCalendar calendar. http://msdn.microsoft.com/en-us/library/ms187819.aspx Date range January 1, 1753, through December 31, 9999 Time range 00:00:00 through 23:59:59.997 Accuracy Rounded to increments of .000, .003, or .007 seconds Arne On Fri, 19 Dec 2008 17:26:41 -0800, tshad <t**@dslextreme.com> wrote:
> What is really strange is that 05/07/08(-4%) is converting to: Why is that strange? Your regex basically removes anything that's not a > > 05/07/084 digit or a '/' character. > Convert.ToDateTime is change this to: 05/07/0084 12:00:00 AM???? Well, what did you expect it to do with the year "084"?> But Sql says it is invalid and gives me an error: I don't know much about SQL, but it looks like the range of valid dates in > > Message: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM > and > 12/31/9999 11:59:59 PM. SQL does not include the year 84. Not that I see any reason you'd _want_ it to accept the year 84, given the original string you started with. > It turns out all of these examples die in SQL but pass in VS. What does that mean? It's clear why the result of your conversion isn't accepted by SQL. But what does it mean for something to "pass in VS"? Show quoteHide quote > The code I use is: Why would you have assumed that the execution would wind up in the "catch" > > public static DateTime? CleanDates(string valueIn) > { > DateTime? datValue = null; > string strValue; > > strValue = Regex.Replace(valueIn, @"[^\d/]", ""); > try > { > datValue = Convert.ToDateTime(strValue); > } > catch > { > datValue = null; > } > return datValue; > } > > I would have assumed it would take the Catch, but doesn't. clause? You had a successful conversion from the string to a DateTime value. As far as the original question goes, you're not being specific enough about what it is you really want to do. It seems to me that if you want to actually extract dates of the form "mm/dd/yy" or "mm/dd/yyyy", you should write a regex pattern that matches _that_, rather than trying to remove all the characters from the string that aren't digits or '/' characters. From your examples, it appears that you always have two-digit months and dates, but may have two- or four-digit years. So, perhaps rather than using the Replace() method, you could use the Match() method, with a string like this: @"\d\d/\d\d/\d\d(\d\d)?" Keeping in mind that I'm no regex expert, and might have something not quite right in that one. But hopefully you get the idea; that is, that there is in fact a specific pattern that you're looking for, so matching against that pattern is likely to be more fruitful than trying to exclude specific characters. Pete
Show quote
Hide quote
"Peter Duniho" <NpOeStPe***@nnowslpianmk.com> wrote in message I know that. I didn't know the range would be that much different from SQL news:op.umftqmxa8jd0ej@petes-computer.local... > On Fri, 19 Dec 2008 17:26:41 -0800, tshad <t**@dslextreme.com> wrote: > >> What is really strange is that 05/07/08(-4%) is converting to: >> >> 05/07/084 > > Why is that strange? Your regex basically removes anything that's not a > digit or a '/' character. > >> Convert.ToDateTime is change this to: 05/07/0084 12:00:00 AM???? > > Well, what did you expect it to do with the year "084"? but it obviously is. > I don't want it to accept this date. The problem is that my regex only gets >> But Sql says it is invalid and gives me an error: >> >> Message: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM >> and >> 12/31/9999 11:59:59 PM. > > I don't know much about SQL, but it looks like the range of valid dates in > SQL does not include the year 84. Not that I see any reason you'd _want_ > it to accept the year 84, given the original string you started with. > rid of everything that is not a number and a "/". This works for about 99% of my dates (out of about 200,000 at the moment). But I would like to figure out a better regex option. >> It turns out all of these examples die in SQL but pass in VS. I mean that it considers it a valid date - which it is but not really THE > > What does that mean? It's clear why the result of your conversion isn't > accepted by SQL. But what does it mean for something to "pass in VS"? valid date. Show quoteHide quote > I agree and that is my problem. It passes (valid) in VS and then dies in >> The code I use is: >> >> public static DateTime? CleanDates(string valueIn) >> { >> DateTime? datValue = null; >> string strValue; >> >> strValue = Regex.Replace(valueIn, @"[^\d/]", ""); >> try >> { >> datValue = Convert.ToDateTime(strValue); >> } >> catch >> { >> datValue = null; >> } >> return datValue; >> } >> >> I would have assumed it would take the Catch, but doesn't. > > Why would you have assumed that the execution would wind up in the "catch" > clause? You had a successful conversion from the string to a DateTime > value. SQL. But SQL is only dropping it because it is outside the date range. That doesn't necessarily making it correct. Being a valid date doesn't make it the correct date. Which is my problem. > I agree. Which was what I was asking. I just wanted to see if anyone knew > As far as the original question goes, you're not being specific enough > about what it is you really want to do. It seems to me that if you want > to actually extract dates of the form "mm/dd/yy" or "mm/dd/yyyy", you > should write a regex pattern that matches _that_, rather than trying to > remove all the characters from the string that aren't digits or '/' > characters. of one off hand. > I agree. I am actually looking for 1 or 2 characters in the days and months > From your examples, it appears that you always have two-digit months and > dates, but may have two- or four-digit years. So, perhaps rather than > using the Replace() method, you could use the Match() method, with a > string like this: @"\d\d/\d\d/\d\d(\d\d)?" Keeping in mind that I'm no > regex expert, and might have something not quite right in that one. But > hopefully you get the idea; that is, that there is in fact a specific > pattern that you're looking for, so matching against that pattern is > likely to be more fruitful than trying to exclude specific characters. and 2 or 4 in the last. Exactly that pattern. Anything else I want to get rid of. Thanks, Tom Show quoteHide quote > > Pete tshad wrote:
Show quoteHide quote > This is really a regex question. For inspiration see below.> > I am wonding if anyone knows a good Regex expression that would pull a valid > date from a string. > > I have used: > > strValue = Regex.Replace(valueIn, @"[^\d/]", ""); > > which works most of the time. > > But I have some cases where I have strings like: > > 05/07/08(-4%) > 09/19/08 DOM 55 > 09/19/2008 DOM 53 > FOR 09/15/08 -23 Arne ======================= using System; using System.Globalization; using System.Text.RegularExpressions; namespace E { public class Program { private static readonly Regex re = new Regex(@"\d{2}/\d{2}/\d{2}", RegexOptions.Compiled); public static DateTime Parse(string s) { return DateTime.Parse(re.Match(s).Value, new CultureInfo("en-US")); } public static void Main(string[] args) { Console.WriteLine(Parse("05/07/08(-4%)")); Console.WriteLine(Parse("09/19/08 DOM 55")); Console.WriteLine(Parse("09/19/2008 DOM 53")); Console.WriteLine(Parse("FOR 09/15/08 -23")); Console.ReadKey(); } } }
Show quote
Hide quote
"Arne Vajhøj" <a***@vajhoej.dk> wrote in message That looks good. Would that handle 1 and 2 digits for days and months and 2 news:494c4fb2$0$90274$14726298@news.sunsite.dk... > tshad wrote: >> This is really a regex question. >> >> I am wonding if anyone knows a good Regex expression that would pull a >> valid date from a string. >> >> I have used: >> >> strValue = Regex.Replace(valueIn, @"[^\d/]", ""); >> >> which works most of the time. >> >> But I have some cases where I have strings like: >> >> 05/07/08(-4%) >> 09/19/08 DOM 55 >> 09/19/2008 DOM 53 >> FOR 09/15/08 -23 > > For inspiration see below. and 4 for years? Thanks, Tom Show quoteHide quote > > Arne > > ======================= > > using System; > using System.Globalization; > using System.Text.RegularExpressions; > > namespace E > { > public class Program > { > private static readonly Regex re = new Regex(@"\d{2}/\d{2}/\d{2}", > RegexOptions.Compiled); > public static DateTime Parse(string s) > { > return DateTime.Parse(re.Match(s).Value, new > CultureInfo("en-US")); > } > public static void Main(string[] args) > { > Console.WriteLine(Parse("05/07/08(-4%)")); > Console.WriteLine(Parse("09/19/08 DOM 55")); > Console.WriteLine(Parse("09/19/2008 DOM 53")); > Console.WriteLine(Parse("FOR 09/15/08 -23")); > Console.ReadKey(); > } > } > } tshad wrote:
Show quoteHide quote > "Arne Vajhøj" <a***@vajhoej.dk> wrote in message @"\d{1,2}/\d{1,2}/\d{2,4}"> news:494c4fb2$0$90274$14726298@news.sunsite.dk... >> tshad wrote: >>> This is really a regex question. >>> >>> I am wonding if anyone knows a good Regex expression that would pull a >>> valid date from a string. >>> >>> I have used: >>> >>> strValue = Regex.Replace(valueIn, @"[^\d/]", ""); >>> >>> which works most of the time. >>> >>> But I have some cases where I have strings like: >>> >>> 05/07/08(-4%) >>> 09/19/08 DOM 55 >>> 09/19/2008 DOM 53 >>> FOR 09/15/08 -23 >> For inspiration see below. > > That looks good. Would that handle 1 and 2 digits for days and months and 2 > and 4 for years? >> private static readonly Regex re = new Regex(@"\d{2}/\d{2}/\d{2}", RegexOptions.Compiled); is more flexible. Arne
Other interesting topics
Inheritance problem
Multi threaded design patterns Mapping Combobox doesn't work if the form has TopMost = true how to convert a byte array with string,int and double embeded? Inherit Overrides Linq.Table<variable> is it possible Do SingleCall server activation objects retain state across calls? Linq To Sql: Contains any. Class and Methods access |
|||||||||||||||||||||||