2017-12-19 4 views
1

Ich habe viele Probleme der String-Indizierung von C# zu Python. Im Grunde erzeugt die vorhandene Datenpipeline (in C#) einige Zeichenfolgenindizes für ein zu konsumierendes Python-Modell. Was passiert ist, dass diese zwei Sprachen verschiedene Codepunkte in ihren jeweiligen Unicode-Systemen verwenden, wie hier zusammengefasst: http://illegalargumentexception.blogspot.com/2010/04/i18n-comparing-character-encoding-in-c.htmlKann ich verschiedene Codepunkte in Python3 verwenden?

Daher sind die Zeichenfolge Länge und Indizes in C# (16-Bit, implizite UTF-16) nicht 100% relevant in Python (16 oder 32). Manchmal generiert Python eine kleinere Zeichenfolge als C#, wenn ein Zeichen mehr als 0xFFFF (mehr als 16 Bit) ist.

Die Frage ist: Gibt es eine Möglichkeit, sicherzustellen, dass die Indexierung und die Längen der Zeichenfolge identisch sind? Ist es möglich, Python zu zwingen, implizite 16-Bit wie in C# zu verwenden?

Ein konkretes Beispiel ist dies:

, Ṣur 

Und seine utf-8 Bytes:

b'\xf0\x90\xa4\x91\xf0\x90\xa4\x85\xf0\x90\xa4\x93, \xe1\xb9\xa2ur' 

In Python, die Länge der Saite 12 ist, wo wie C# Berichte 15. Indizierung wird auch von einer Sprache zur anderen.

+0

Das ist keine Zeichenfolge in Python: Es ist eine Sequenz von rohen Bytes. –

+0

Es ist eine Zeichenfolge ", Ṣur" mit utf-8-Codierung. Seit dem Kopieren und Einfügen sind die Zeichen möglicherweise nicht reproduzierbar. Ich kopiere und füge die Bytes für die Untersuchung ein. –

+0

Wenn Sie '.decode ('utf-8')' aufrufen, haben Sie eine Zeichenfolge. Aber was Sie gezeigt haben, ist keine Zeichenfolge. –

Antwort

2

Sie wollen wahrscheinlich die StringInfo Klasse pro diese Antwort verwenden hier: Why is the length of this string longer than the number of characters in it?

using System; 
using System.Text; 
using System.Globalization; 

namespace StackOverflow { 
    class Program { 
     public static void Main(string[] args) { 
      var s = ", Ṣur"; 
      // Len == 11 
      Console.WriteLine("{0}: {1}", s, s.Length); 

      // len == 8 
      var si = new StringInfo(s); 
      Console.WriteLine("{0}: {1}", s, si.LengthInTextElements); 
     } 
    } 
} 

Oder auf der Seite Python, können Sie dies versuchen können, aber es ist nicht ganz identisch mit C# 's Länge, weil es 2- annimmt, Bytes, so dass es nur die ersten 65.536 UTF-16 Zeichen umfasst:

#!/usr/bin/env python3 

s = ", Ṣur" 
# len == 8 (displayable len) 
print("{}: {}".format(s, len(s))) 

# len == 11 (C# wackiness) 
print(int(len(s.encode("utf-16"))/2) - 1) 
+1

Danke! Dies löst die Richtung von C# zu Python. Hast du irgendwelche Vorschläge für die andere Richtung von Python zu C#? –

+0

Nur aus Neugier: Wenn Sie Diakritika kombinieren, wird StringInfo sie als separate Zeichen zählen? Wenn nicht, wird sich das wiederum davon unterscheiden, wie Python Zeichen zählt ... – lenz

+0

@YoHsiao - Ich habe ein halb äquivalentes UTF-16-Beispiel für Python hinzugefügt. – mattmc3

Verwandte Themen