首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从字符串中间执行区分区域性的“starts with”操作?

如何从字符串中间执行区分区域性的“starts with”操作?
EN

Stack Overflow用户
提问于 2013-04-13 04:28:42
回答 3查看 6.3K关注 0票数 107

我有一个相对模糊的需求,但我觉得使用BCL应该是可能的。

对于上下文,我正在解析Noda Time中的日期/时间字符串。我为我在输入字符串中的位置维护一个逻辑游标。因此,虽然完整的字符串可能是“2013年1月3日”,但逻辑光标可能在'J‘处。

现在,我需要解析月份名称,将其与区域性的所有已知月份名称进行比较:

从游标点开始的月份(不是晚些时候;我想看看光标是否正在“查看”候选月份name)

  • Quickly

  • ...然后我需要知道

用了多少个字符

使用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))

但是:

  • ,这需要我创建一个子字符串,而我真的不想这样做。(我将Noda Time视为一个有效的系统库;解析性能对某些客户机可能非常重要。)
  • 它没有告诉我在

之后应该将游标前进多远。

实际上,我强烈怀疑这不会经常出现……但我真的想在这里做正确的事情。我也真的希望能够做到这一点,而不是成为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”可以很好地进行解析。

好的,还有几个数据点:

  • 使用SubstringIsPrefix的成本是可观的,但并不可怕。在我的开发笔记本电脑上的一个示例“星期五4月12日20:28:42”中,它将我在一秒钟内可以执行的解析操作的数量从大约460K更改为大约400K。如果可能的话,我宁愿避免这种减速,但它并不太像我想的那样不太可行--因为它在可移植类库中不可用。我可能只将它用于非PCL构建,允许PCL构建不太正确。标准化测试(string.IsNormalized)的性能影响将性能降低到大约每秒445K次调用,这是我可以接受的。我仍然不确定它是否做了我需要的所有事情-例如,在许多文化中,包含“«”的月份名称应该与"ss“匹配,我相信……而规范化并不能做到这一点。
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15980310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档