我有一个相对模糊的需求,但我觉得使用BCL应该是可能的。
对于上下文,我正在解析Noda Time中的日期/时间字符串。我为我在输入字符串中的位置维护一个逻辑游标。因此,虽然完整的字符串可能是“2013年1月3日”,但逻辑光标可能在'J‘处。
现在,我需要解析月份名称,将其与区域性的所有已知月份名称进行比较:
从游标点开始的月份(不是晚些时候;我想看看光标是否正在“查看”候选月份name)
用了多少个字符
使用CompareInfo.Compare
,执行此操作的current code通常可以工作。它实际上是这样的(只是为了匹配部分-在真实的东西中有更多的代码,但它与匹配无关):
internal bool MatchCaseInsensitive(string candidate, CompareInfo compareInfo)
{
return compareInfo.Compare(text, position, candidate.Length,
candidate, 0, candidate.Length,
CompareOptions.IgnoreCase) == 0;
}
然而,这取决于候选者和我们比较的区域是相同的长度。大多数情况下都很好,但在某些特殊情况下就不好了。假设我们有这样的东西:
// U+00E9 is a single code point for e-acute
var text = "x b\u00e9d y";
int position = 2;
// e followed by U+0301 still means e-acute, but from two code points
var candidate = "be\u0301d";
现在我的比较就失败了。我可以使用IsPrefix
if (compareInfo.IsPrefix(text.Substring(position), candidate,
CompareOptions.IgnoreCase))
但是:
之后应该将游标前进多远。
实际上,我强烈怀疑这不会经常出现……但我真的想在这里做正确的事情。我也真的希望能够做到这一点,而不是成为Unicode专家或自己实现它:)
(在Noda Time中以bug 210的形式提出,以防有人想要了解任何最终结论。)
我喜欢规范化的想法。我需要详细检查a)正确性和b)性能。假设我可以让它正常工作,我仍然不确定它是否值得全部改变-这类事情在现实生活中可能永远不会出现,但可能会损害我所有用户的性能:
我还检查了BCL -它似乎也没有正确地处理这个问题。示例代码:
using System;
using System.Globalization;
class Test
{
static void Main()
{
var culture = (CultureInfo) CultureInfo.InvariantCulture.Clone();
var months = culture.DateTimeFormat.AbbreviatedMonthNames;
months[10] = "be\u0301d";
culture.DateTimeFormat.AbbreviatedMonthNames = months;
var text = "25 b\u00e9d 2013";
var pattern = "dd MMM yyyy";
DateTime result;
if (DateTime.TryParseExact(text, pattern, culture,
DateTimeStyles.None, out result))
{
Console.WriteLine("Parsed! Result={0}", result);
}
else
{
Console.WriteLine("Didn't parse");
}
}
}
将自定义月份名称更改为"bed“并使用文本值"bEd”可以很好地进行解析。
好的,还有几个数据点:
Substring
和IsPrefix
的成本是可观的,但并不可怕。在我的开发笔记本电脑上的一个示例“星期五4月12日20:28:42”中,它将我在一秒钟内可以执行的解析操作的数量从大约460K更改为大约400K。如果可能的话,我宁愿避免这种减速,但它并不太像我想的那样不太可行--因为它在可移植类库中不可用。我可能只将它用于非PCL构建,允许PCL构建不太正确。标准化测试(string.IsNormalized
)的性能影响将性能降低到大约每秒445K次调用,这是我可以接受的。我仍然不确定它是否做了我需要的所有事情-例如,在许多文化中,包含“«”的月份名称应该与"ss“匹配,我相信……而规范化并不能做到这一点。https://stackoverflow.com/questions/15980310
复制相似问题