문제

문제 : 외부 시스템에서 두 개의 고정 너비 문자열이 있습니다. 첫 번째에는 기본 문자 (AZ : AZ)가 포함되어 있으며, 두 번째 (5 월)에는 실제 문자를 만들기 위해 첫 번째 문자열에 추가되는 디아크리닉이 포함되어 있습니다.

string asciibase = "Dutch has funny chars: a,e,u";
string diacrits  = "                       ' \" \"";

//no clue what to do

string result = "Dutch has funny chars: á,ë,ü";

나는 대규모 검색을 작성하고 모든 캐릭터 + 다른 Diacritics를 대체 할 수 있었지만 좀 더 우아한 것을 기대하고있었습니다.

누군가 이것을 고치는 방법에 대한 단서가 있습니까? 문자열을 사용하여 소수점 값을 계산하여 시도했지만 결과는 없었습니다. 또한 Google은 실제로 무언가로 나타나지 않았습니다.

도움이 되었습니까?

해결책

조회 테이블을 사용하는 것 외에는 쉬운 솔루션을 찾을 수 없습니다.

public void TestMethod1()
{
    string asciibase = "Dutch has funny chars: a,e,u";
    string diacrits = "                       ' \" \"";
    var merged = DiacritMerger.Merge(asciibase, diacrits);
}

편집 : @jonb 및 @oliver의 답변에서 제안한 후 단순화 된 코드

public class DiacritMerger
{
    static readonly Dictionary<char, char> _lookup = new Dictionary<char, char>
                         {
                             {'\'', '\u0301'},
                             {'"', '\u0308'}
                         };

    public static string Merge(string asciiBase, string diacrits)
    {
        var combined = asciiBase.Zip(diacrits, (ascii, diacrit) => DiacritVersion(diacrit, ascii));
        return new string(combined.ToArray());
    }

    private static char DiacritVersion(char diacrit, char character)
    {
        char combine;
        return _lookup.TryGetValue(diacrit, out combine) ? new string(new [] {character, combine}).Normalize()[0] : character;
    }
}

다른 팁

Diacritical Marks 범위를 결합한 유니 코드에서 적절한 유니 코드 값으로 디아크리닉을 변환하십시오.

http://www.unicode.org/charts/pdf/u0300.pdf

그런 다음 char와 그 diacritic을 e-acute, u+0065 = "e"및 u+0301 = 급성에 대해 char와 diacritic을 두드리십시오.

  String s = "\u0065\u0301";

그 다음에:

  string normalisedString = s.Normalize();

둘을 새 문자열로 결합합니다.

문제는 지정된 직경이 명시 적으로 구문 분석되어야한다는 것입니다. 이중 점이 단독으로 존재하지 않으므로이 경우에는 이중 인용문이 사용됩니다. 따라서 문제를 해결하려면 다른 기회가없고 필요한 각 사례를 구현할 수 없습니다.

여기에 단서를 얻는 출발점이 있습니다 ...

    public SomeFunction()
    {
        string asciiChars = "Dutch has funny chars: a,e,u";
        string diacrits = "                       ' \" \"";

        var combinedChars = asciiChars.Zip(diacrits, (ascii, diacrit) =>
        {
            return CombineChars(ascii, diacrit);
        });

        var Result = new String(combinedChars.ToArray());
    }

    private char CombineChars(char ascii, char diacrit)
    {
        switch (diacrit)
        {
            case '"':
                return AddDoublePoints(ascii);
            case '\'':
                return AddAccent(ascii);
            default:
                return ascii;
        }
    }

    private char AddDoublePoints(char ascii)
    {
        switch (ascii)
        {
            case 'a':
                return 'ä';
            case 'o':
                return 'ö';
            case 'u':
                return 'ü';
            default:
                return ascii;
        }
    }

    private char AddAccent(char ascii)
    {
        switch (ascii)
        {
            case 'a':
                return 'á';
            case 'o':
                return 'ó';
            default:
                return ascii;
        }
    }
}

ienumerable.zip은 이미 있습니다 .NET 4에서 구현되었습니다, 그러나 3.5로 얻으려면이 코드가 필요합니다 (Eric Lippert에서 가져 왔습니다):

public static class IEnumerableExtension
{
    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>
        (this IEnumerable<TFirst> first,
        IEnumerable<TSecond> second,
        Func<TFirst, TSecond, TResult> resultSelector)
    {
        if (first == null) throw new ArgumentNullException("first");
        if (second == null) throw new ArgumentNullException("second");
        if (resultSelector == null) throw new ArgumentNullException("resultSelector");
        return ZipIterator(first, second, resultSelector);
    }

    private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>
        (IEnumerable<TFirst> first,
        IEnumerable<TSecond> second,
        Func<TFirst, TSecond, TResult> resultSelector)
    {
        using (IEnumerator<TFirst> e1 = first.GetEnumerator())
        using (IEnumerator<TSecond> e2 = second.GetEnumerator())
            while (e1.MoveNext() && e2.MoveNext())
                yield return resultSelector(e1.Current, e2.Current);
    }
}

C#또는 표준 라이브러리를 모르지만 하나의 대안 적 접근 방식은 기존 HTML/SGML/XML 문자 엔티티 파서/렌더러와 같은 것을 사용하거나 실제로 브라우저에 제시하려는 경우 아무것도 아님!

의사 코드 :

for(i=0; i < strlen(either_string); i++) {
  if isspace(diacrits[i]) {
     output(asciibase[i]);
  }else{
     output("&");
     output(asciibase[i]);
     switch (diacrits[i]) {
       case '"' : output "uml"; break;
       case '^' : output "circ"; break;
       case '~' : output "tilde"; break;
       case 'o' : output "ring"; break;
       ... and so on for each "code" in the diacrits modifier
       ... (for acute, grave, cedil, lig, ...)
     }
     output(";");
  }
}

따라서, A + o -> &Aring;, u + " -> &uuml; 등등.

그런 다음 HTML 엔티티를 구문 분석 할 수 있다면 집에 무료로 있어야하며 숯 사이에 휴대용이 있어야합니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top