2017-10-10 4 views
0

私は、ASCIIベースのプロトコルを使ってTelnetセッションを介してデバイスとやりとりする簡単なアプリケーションに取り組んでいます。Regexを使ってASCIIプロトコルを解析する

デバイスとのやりとりがたくさんあるので、入ってくる文字列を高速に解析する方法を探しています。今、メーカーはRegexスキームをリリースするのにとても親切でした。しかし、Regexは私にとって非常に新しいので、私は値を取得する方法を理解していません。私はどのように一致するか知っているが、私はそれから値を取得したいと一致するとき。応答の

正規表現スキーム

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

例Iは、文書をたくさん読んで、たくさんのアプローチのを試してみた

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

、しかし誰かが右、直接に私を指摘することができます。

しかし、私は、コマンドとその値のインデックス位置を見つけて、部分文字列を使用して値だけを取得する単純なパーサーを作成しました。それは動作しますが、私はRegexの力で "より良い"方法を好みます。

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

より詳細な "構文解析" の要件を提供するために、@VBobCatのリクエスト。

それでは、私はプロパティFooBarを持つオブジェクトを持っていると私はTelnet経由の文字列を受信したとき、我々は、私はそれらのいずれかにそれを解析する必要が今のプロパティcatdog

との第2の目的を持っているとしましょうオブジェクト。幸いなことに、文字列は常にその文字列で始まります。したがって、FooとBarのオブジェクトの場合はx、catとdogのオブジェクトの場合はanimalとします。

ここで提供されているRegexでは、文字列の値をオブジェクトのプロパティに解析します。以下のような何か:

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

OR

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

あなたは同じ言語を動作し、認識パーサを持っている場合おそらく、すでに正規表現の束よりも読みやすいものがあるでしょう。上の正規表現のリストは、ストリームからトークンを取得する方法の説明にすぎませんが、実際には文法を記述するものではありません。 – Joey

+0

ありがとうございますが、現在の関数は、特定のインデックス位置に対してちょっと敏感です。また、私はRegexが文字列を解析する非常に高速なメソッドである可能性がどこでも読んでいます。 – Gforse

答えて

0

すべてのサンプルはあなたの例と一致している場合、これは仕事ができる:

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

この機能をお寄せいただきありがとうございます。本当に有望ですね。私は異なるRegex関数と関数でいくつかのテストを行い、速度を記録しました。テストでは、関数ごとに500回繰り返しました。これは結果でした: – Gforse

+0

これは結果でした:Split Func:6619,7564 Match Func:12105,4255 Func:11945,3395 ParseTelnet Func:1023,5577あなたが見るとおり、あなたは非常に高速です。しかし、欠陥がありますが、改行は削除されません。どのように文字列をオブジェクトに解析するために、このコードを再構築しますか?プロトコルには、異なるオブジェクトをもたらす異なるタイプのコマンドがあります。文字列の最初の3文字は – Gforse

+0

@Gforseと定義されています。長いサンプルを投稿するために質問を編集して、データをグループ化する方法を正確に定義できますか?つまり、各行を別々のエンティティにしたいですか? – VBobCat

関連する問題