2010-10-22 18 views
2

J'ai un tableau de données d'octets UTF-8. Je voudrais rechercher une chaîne spécifique dans le tableau d'octets en C#.Comment puis-je trouver l'index de départ d'une chaîne dans un tableau d'octets UTF-8? (C#)

byte[] dataArray = (some UTF-8 byte array of data);

string searchString = "Hello";

Comment puis-je trouver la première occurrence du mot « Bonjour » dans le tableau tableauDonnees et retourner un emplacement de l'index où la chaîne commence (où le « H » de « Bonjour » serait situé dans dataArray)?

Avant, j'utilisais à tort quelque chose comme:

int helloIndex = Encoding.UTF8.GetString(dataArray).IndexOf("Hello");

De toute évidence, ce code ne serait pas garanti de travailler depuis que je suis de retour l'index d'une chaîne, et non l'indice de l'UTF-8 tableau d'octets. Existe-t-il des méthodes C# intégrées ou des codes éprouvés et efficaces que je peux réutiliser?

Merci,

Matt

Répondre

4

Une des fonctionnalités intéressantes sur UTF-8 est que si une séquence d'octets représente un caractère et cette séquence d'octets apparaît partout dans UTF-8 valides données codées puis représente toujours ce personnage. Sachant cela, vous pouvez convertir la chaîne que vous cherchez en un tableau d'octets, puis utiliser le Boyer-Moore string searching algorithm (ou tout autre algorithme de recherche de chaîne que vous aimez) adapté légèrement pour travailler sur des tableaux d'octets au lieu de chaînes.

Il y a un certain nombre de réponses ici qui peuvent vous aider:

+0

Je sais qu'il est tard pour le souligner, mais je Je trouve personnellement qu'il y a un conflit avec les connaissances que j'ai acquises de la publication de @JoelSpolky [Le minimum absolu que chaque développeur de logiciels doit absolument, positivement doit savoir sur Unicode et Jeux de caractères (pas d'excuses!)] (Http://www.joelonsoftware.com/articles/Unicode.html). Ce que vous dites est ceci: Si j'ai par exemple la chaîne 'var nl =" \ n ";' qui donne exactement un octet lors du codage en UTF8 'var bytes = new byte [] {10}' dont la valeur est ' 10' alors cela doit signifier que '10' ** ne peut jamais ** représenter la moitié ou le tiers d'un personnage chinois? –

+0

Je n'essaie pas de dire que votre idée est même partiellement erronée. Je suis juste un peu confus au sujet de ce que vous dites et je veux clarifier les choses pour moi et peut-être d'autres. –

+0

"cela doit signifier que 10 ne peut jamais représenter la moitié ou le tiers d'un caractère chinois" Je pense que c'est correct. Voir https://en.wikipedia.org/wiki/UTF-8#Description. Tous les octets de caractères multi-octets sont plus grands que le binaire 10000000 (0x80) qui est plus grand que "\ n" (0x10). –

0

Essayez l'extrait suivant:

// Setup our little test. 

string sourceText = "ʤhello"; 

byte[] searchBytes = Encoding.UTF8.GetBytes(sourceText); 

// Convert the bytes into a string we can search in. 

string searchText = Encoding.UTF8.GetString(searchBytes); 

int position = searchText.IndexOf("hello"); 

// Get all text that is before the position we found. 

string before = searchText.Substring(0, position); 

// The length of the encoded bytes is the actual number of UTF8 bytes 
// instead of the position. 

int bytesBefore = Encoding.UTF8.GetBytes(before).Length; 

// This outputs Position is 1 and before is 2. 

Console.WriteLine("Position is {0} and before is {1}", position, bytesBefore);