0

我正在寻找一种优雅的方法来解析可能具有别名标记(例如“AKA”和“FKA”)的法庭案件标题。我需要检索别名类型以及以下标题。我已经蛮力解决了,但想看看还有什么其他选择。我喜欢 Linq 并尝试过 Sprache,但无法完全理解它。

Example caption:
JOHN SMITH AKA JOHN R SMITH FKA JOHNNY R SMITH  

Desired output: 
Alias Type Found: AKA   
Alias Caption Found: JOHN R SMITH   
Alias Type Found: FKA   
Alias Caption Found: JOHNNY R SMITH

以下是到目前为止我在 LinqPad 中汇总的内容。

void Main()
{
    var caption = "JOHN SMITH AKA JOHN R SMITH FKA JOHNNY R SMITH";
    caption.Split().ParseAliases( (t,c)=>{
        Console.WriteLine ("Alias Type Found: {0}",t);
        Console.WriteLine ("Alias Caption Found: {0}",c);
    });
}

public delegate void AliasRetrievedDelegate(string aliasType, string aliasCaption);

public static class ParserExtensions{
    private static IEnumerable<string> aliasTypes = new[]{"AKA","FKA"};

    public static void ParseAliases(this IEnumerable<string> tokens, 
        aliasRetrievedDelegate d, 
        int startIdx = 0){
                   // TODO

    }
}
4

1 回答 1

0

这可能不像您想要的那样优雅,但它确实有效。它将别名类型与以下字符串列表分组。然后它连接字符串以形成相应的别名。

public static class ParserExtensions
{
    private static IEnumerable<string> aliasTypes = new[]{"AKA","FKA"};

    public static void ParseAliases(this IEnumerable<string> tokens, 
        Action<string, string> d, 
        int startIdx = 0)
    {
        var aliases = tokens.Skip(startIdx)
                            .GroupMatchesWithTrailing(x => aliasTypes.Contains(x));
        foreach(var alias in aliases)
        {
            string aliasType = alias.Item1;
            string aliasName = string.Join(" ", alias.Item2.ToArray());
            d(alias.Type, alias.Name);
        }   
    }

棘手的部分是将别名类型与相应的名称分组。这种方法相当冗长,但source只迭代一次并且可以懒惰地评估。还有更简洁的解决方案,但它们有权衡。

    private static IEnumerable<Tuple<T, List<T>>> GroupMatchesWithTrailing<T>(
        this IEnumerable<T> source,
        Func<T, bool> predicate)
    {
        var items = source.SkipWhile(x => predicate(x) == false);
        using (IEnumerator<T> iterator = items.GetEnumerator())
        {
            bool hasItems = iterator.MoveNext();
            while(hasItems)
            {
                T match = iterator.Current;
                List<T> trailing = new List<T>();
                hasItems = iterator.MoveNext();
                while(hasItems && predicate(iterator.Current) == false)
                {
                    trailing.Add(iterator.Current);
                    hasItems = iterator.MoveNext();
                }
                yield return Tuple.Create(match, trailing);
            }
        }
    }
}
于 2012-09-30T02:36:36.350 回答