2017-10-10 12 views
0

Je travaille sur une application simple qui interagit avec un périphérique via une session Telnet avec un protocole ASCII.Utilisation de Regex pour analyser le protocole ASCII

Il y aura beaucoup d'interaction avec l'appareil, donc je cherche un moyen rapide d'analyser la chaîne entrante. Maintenant, le fabricant a eu la gentillesse d'y publier Regex. Mais puisque Regex est très nouveau pour moi, je ne comprends pas comment récupérer la valeur. Je sais comment faire correspondre mais quand je fais correspondre je veux obtenir la valeur de cela.

système Regex

NameAndValue := [A-Z_]+:("(\\.|[^"\\])*"|(\\.|[^\s"\\])*) 
Value := ("(\\.|[^"\\])*"|(\\.|[^\s"\\])*) 
ValueUnquoted := (\\.|[^\s"\\])* 
ValueQuoted := "(\\.|[^"\\])*" 
CharQuoted := (\\.|[^"\\]) 
CharUnquoted := (\\.|[^\s"\\]) 
EscapedChar := \\. 
CharCommon := [^\s"\\] 
CharEscape := \\ 
CharQuote := " 
CharSpace := \s 

Exemple d'une réponse

CMD1:"string value" CMD2:1 CMD3:"string value again" <LF> or <CR>+<LF> 

J'ai lu beaucoup de documentation et beaucoup a essayé d'approches, mais quelqu'un pourrait me diriger dans le droit direct.

J'ai cependant écrit un simple analyseur qui trouve les positions d'index des commandes et de leurs valeurs, puis utilise une sous-chaîne pour récupérer uniquement la valeur. Cela fonctionne, mais je préfère un moyen "plus agréable" avec la puissance de Regex.

--------- EDIT 18-10-2017 ---------

Demande de @VBobCat pour fournir une exigence de "l'analyse" plus détaillée.

Alors disons que j'ai un objet avec les propriétés Foo et Bar et nous avons un deuxième objet avec les propriétés cat et dog

Maintenant, quand je reçois la chaîne via telnet je dois analyser à un de ces objets. Heureusement, la chaîne commence toujours par ce qu'elle contient. Alors disons x pour objet avec Foo et Bar et animal pour objet avec chat et chien.

Maintenant, avec le Regex fourni je veux analyser les valeurs dans la chaîne pour les propriétés de l'objet. Quelque chose comme:

X CMD1_Foo:1 CMD2_Bar:"string value" <LF> or <CR>+<LF> 
Object X.Foo = CMD1_Foo.value 
Object X.Bar = CMD2_Bar.value 

OU

Animal CMD1_Cat:"Miauw" CMD2_Dog:"woef" <LF> or <CR>+<LF> 
Object X.Cat = CMD1_Cat.value 
Object X.Dog = CMD2_Dog.value 
+0

Si vous avez un analyseur qui fonctionne et reconnaît la même langue , alors vous avez probablement déjà quelque chose de plus lisible qu'un tas de regex. La liste des expressions rationnelles ci-dessus semble être juste une description de la façon d'obtenir des jetons du flux, mais ne décrit pas réellement la grammaire. – Joey

+0

Merci, mais la fonction actuelle est un peu sensible pour une position d'index spécifique. Aussi je lis partout que Regex pourrait être une méthode très rapide pour analyser les chaînes. – Gforse

Répondre

0

Si tous vos échantillons sont compatibles avec votre exemple, cela pourrait fonctionner:

Function ParseTelnet(input As String) As DataTable 
    Dim retTable As New DataTable 
    retTable.Columns.Add("command", GetType(String)) 
    retTable.Columns.Add("value", GetType(String)) 
    Dim entries = System.Text.RegularExpressions.Regex.Split(input, "\s+(?=\w+:)") 
    Dim pairs = entries.Select(
     Function(entry) If(entry, "").Trim(Chr(9), Chr(10), Chr(13), Chr(32)).Split({":"c}, 2)).Where(
     Function(pair) pair.Count = 2) 
    For Each pair In pairs 
     If pair(1).StartsWith("""") AndAlso pair(1).EndsWith("""") Then 
      retTable.Rows.Add(pair(0), pair(1).Substring(1, pair(1).Length - 2)) 
     Else 
      retTable.Rows.Add(pair(0), pair(1)) 
     End If 
    Next 
    Return retTable 
End Function 
+0

Merci pour la fonction. Ça a l'air vraiment prometteur. J'ai fait quelques tests avec différentes fonctions Regex et votre fonction et enregistré la vitesse. Pour le test, il a bouclé 500 fois par fonction. Ce fut le résultat: – Gforse

+0

Cela a été le résultat: Split Func: 6619,7564 Match Func: 12105,4255 Correspondances Func: 11945,3395 ParseTelnet Func: 1023,5577 Comme vous pouvez le voir, votre fonction est très rapide. Cependant, il a un défaut, il ne supprime pas les sauts de ligne. Comment voulez-vous reconstruire ce code pour analyser la chaîne à un objet. Le protocole a un type de commande différent qui résulte en différents objets.Les 3 premiers caractères de la chaîne définissent – Gforse

+0

@Gforse. Pourriez-vous éditer votre question afin de poster un échantillon plus long et définir exactement comment vous souhaitez que vos données soient regroupées? Autrement dit, voulez-vous que chaque ligne soit une entité distincte? – VBobCat