Handling of english number parsing for reminders
This commit is contained in:
parent
1493480a66
commit
c5b7fb1b83
|
@ -8,7 +8,7 @@ namespace DeukBot4.MessageHandlers
|
||||||
{
|
{
|
||||||
public static class ReminderHandler
|
public static class ReminderHandler
|
||||||
{
|
{
|
||||||
private static Regex ReminderMatcher =
|
private static readonly Regex ReminderMatcher =
|
||||||
new Regex(
|
new Regex(
|
||||||
@".*(remind\s*((?<recipient>me)|<@!*(?<recipient>\d*)>)\s*to)(?<action>.*)(in\s+)(?<time>.*)",
|
@".*(remind\s*((?<recipient>me)|<@!*(?<recipient>\d*)>)\s*to)(?<action>.*)(in\s+)(?<time>.*)",
|
||||||
RegexOptions.IgnoreCase);
|
RegexOptions.IgnoreCase);
|
||||||
|
@ -49,7 +49,7 @@ namespace DeukBot4.MessageHandlers
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Regex TimespanMatcher =
|
private static Regex TimespanMatcher =
|
||||||
new Regex(@"(?<timeNumber>\d+.?\d*)\s*(?<timeId>minutes*|hours*|days*|weeks*|months*|years*)\W*(and )*",
|
new Regex(@"(?<timeNumber>\d+.?\d*|[\w\s-]+)\s*(?<timeId>minutes*|hours*|days*|weeks*|months*|years*)\W*(and )*",
|
||||||
RegexOptions.IgnoreCase);
|
RegexOptions.IgnoreCase);
|
||||||
private static TimeSpan? ParseTime(string message)
|
private static TimeSpan? ParseTime(string message)
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,14 @@ namespace DeukBot4.MessageHandlers
|
||||||
if (!match.Success)
|
if (!match.Success)
|
||||||
continue;
|
continue;
|
||||||
var timeId = match.Groups["timeId"].Value.ToLowerInvariant();
|
var timeId = match.Groups["timeId"].Value.ToLowerInvariant();
|
||||||
var timeAmount = double.Parse(match.Groups["timeNumber"].Value);
|
var amountString = match.Groups["timeNumber"].Value;
|
||||||
|
if (!double.TryParse(amountString, out var timeAmount))
|
||||||
|
{
|
||||||
|
if (!EnglishNumberParser.ConvertNumberString(amountString, out timeAmount))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (timeId.StartsWith("minute"))
|
if (timeId.StartsWith("minute"))
|
||||||
timespan += TimeSpan.FromMinutes(timeAmount);
|
timespan += TimeSpan.FromMinutes(timeAmount);
|
||||||
else if (timeId.StartsWith("hour"))
|
else if (timeId.StartsWith("hour"))
|
||||||
|
@ -93,5 +100,6 @@ namespace DeukBot4.MessageHandlers
|
||||||
|
|
||||||
return timespan;
|
return timespan;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DeukBot4.Utilities
|
||||||
|
{
|
||||||
|
public class EnglishNumberParser
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, int> OneValues = new Dictionary<string, int>()
|
||||||
|
{
|
||||||
|
{"zero", 0}, {"a", 1}, {"an", 1}, {"one", 1}, {"two", 2}, {"three", 3}, {"four",4}, {"five", 5}, {"six", 6}, {"seven", 7},
|
||||||
|
{"eight", 8}, {"nine", 9}
|
||||||
|
};
|
||||||
|
private static readonly Dictionary<string, int> TenValues = new Dictionary<string, int>()
|
||||||
|
{
|
||||||
|
{"ten", 10}, {"eleven", 11}, {"twelve", 12}, {"thirteen", 13}, {"fourteen", 14}, {"fifteen", 15},
|
||||||
|
{"sixteen", 16}, {"seventeen", 17}, {"eighteen", 18}, {"nineteen", 19},
|
||||||
|
|
||||||
|
{"twenty", 20}, {"thirty", 30}, {"forty",40}, {"fifty", 50}, {"sixty", 60}, {"seventy", 70},
|
||||||
|
{"eighty", 80}, {"ninety", 90}
|
||||||
|
};
|
||||||
|
private static readonly Dictionary<string, int> HundredsValues = new Dictionary<string, int>()
|
||||||
|
{
|
||||||
|
{"hundred", 100}, {"thousand",1000}, {"million", 1_000_000}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public static bool ConvertNumberString(string numberString, out double number)
|
||||||
|
{
|
||||||
|
numberString = numberString.Replace("-", "").Replace(" ", "");
|
||||||
|
var i = 0;
|
||||||
|
while (numberString.Length > 0)
|
||||||
|
{
|
||||||
|
var next = ConvertNextNumber(ref numberString);
|
||||||
|
if (!next.HasValue)
|
||||||
|
{
|
||||||
|
number = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i += next.Value;
|
||||||
|
}
|
||||||
|
number = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int? ConvertNextNumber(ref string numberString)
|
||||||
|
{
|
||||||
|
foreach (var oneValue in OneValues)
|
||||||
|
{
|
||||||
|
if (numberString.EndsWith(oneValue.Key, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
numberString = numberString.Substring(0, numberString.Length - oneValue.Key.Length);
|
||||||
|
return oneValue.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var oneValue in TenValues)
|
||||||
|
{
|
||||||
|
if (numberString.EndsWith(oneValue.Key, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
numberString = numberString.Substring(0, numberString.Length - oneValue.Key.Length);
|
||||||
|
return oneValue.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var oneValue in HundredsValues)
|
||||||
|
{
|
||||||
|
if (numberString.EndsWith(oneValue.Key, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
numberString = numberString.Substring(0, numberString.Length - oneValue.Key.Length);
|
||||||
|
var value = oneValue.Value;
|
||||||
|
var next = ConvertNextNumber(ref numberString);
|
||||||
|
if (next.HasValue)
|
||||||
|
{
|
||||||
|
if ((int)Math.Log10(next.Value) <= (int)Math.Log10(value))
|
||||||
|
value *= next.Value;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value += next.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue