2012-09-29 2 views
0

"AKA"및 "FKA"와 같은 별칭 토큰이있는 법원의 사례 캡션을 구문 분석하는 우아한 방법을 찾고 있습니다. 다음 캡션과 마찬가지로 별칭 유형을 검색해야합니다. 짐승 같은 솔루션을 강요했지만 다른 옵션이 있는지보고 싶습니다. 나는 Linq를 좋아하고 Sprache를 시도했지만 그 주위에 내 머리를 감쌀 수 없었다.우아한 LINQ 텍스트 구문 분석 옵션이 있습니까?

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 

    } 
} 
+0

LINQ가 아닌 정규식 작업과 비슷합니다. –

+0

저의 생각은 저의 첫 번째 생각이었습니다. 좀 더 쉽게 확장 할 수있는 미니 DSL 라인을 따라 좀 더 읽기 쉬운 솔루션을 원합니다. – Ken

답변

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); 
      } 
     } 
    } 
} 
+0

멋진 Tuple에는 공장 방법이 있습니다. 내가 기대했던 것만은 아니지만 작동하지만 앞으로는 단순화를 위해 도메인 특정 언어를 읽고 있습니다. – Ken